]> git.hungrycats.org Git - linux/commitdiff
v2.4.7.6 -> v2.4.7.7
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:08:13 +0000 (20:08 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:08:13 +0000 (20:08 -0800)
  - me: sane and nice VM balancing
  - Jeff Hartmann: upgrade DRM to XF86 4.1.x, drop support for 4.0.x

86 files changed:
Makefile
drivers/char/drm/Config.in
drivers/char/drm/Makefile
drivers/char/drm/agpsupport.c [deleted file]
drivers/char/drm/ati_pcigart.h [new file with mode: 0644]
drivers/char/drm/auth.c [deleted file]
drivers/char/drm/bufs.c [deleted file]
drivers/char/drm/context.c [deleted file]
drivers/char/drm/ctxbitmap.c [deleted file]
drivers/char/drm/dma.c [deleted file]
drivers/char/drm/drawable.c [deleted file]
drivers/char/drm/drm.h
drivers/char/drm/drmP.h
drivers/char/drm/drm_agpsupport.h [new file with mode: 0644]
drivers/char/drm/drm_auth.h [new file with mode: 0644]
drivers/char/drm/drm_bufs.h [new file with mode: 0644]
drivers/char/drm/drm_context.h [new file with mode: 0644]
drivers/char/drm/drm_dma.h [new file with mode: 0644]
drivers/char/drm/drm_drawable.h [new file with mode: 0644]
drivers/char/drm/drm_drv.h [new file with mode: 0644]
drivers/char/drm/drm_fops.h [new file with mode: 0644]
drivers/char/drm/drm_init.h [new file with mode: 0644]
drivers/char/drm/drm_ioctl.h [new file with mode: 0644]
drivers/char/drm/drm_lists.h [new file with mode: 0644]
drivers/char/drm/drm_lock.h [new file with mode: 0644]
drivers/char/drm/drm_memory.h [new file with mode: 0644]
drivers/char/drm/drm_proc.h [new file with mode: 0644]
drivers/char/drm/drm_scatter.h [new file with mode: 0644]
drivers/char/drm/drm_stub.h [new file with mode: 0644]
drivers/char/drm/drm_vm.h [new file with mode: 0644]
drivers/char/drm/ffb.h [new file with mode: 0644]
drivers/char/drm/ffb_context.c
drivers/char/drm/ffb_drv.c
drivers/char/drm/fops.c [deleted file]
drivers/char/drm/gamma.h [new file with mode: 0644]
drivers/char/drm/gamma_dma.c
drivers/char/drm/gamma_drv.c
drivers/char/drm/gamma_drv.h
drivers/char/drm/i810.h [new file with mode: 0644]
drivers/char/drm/i810_bufs.c [deleted file]
drivers/char/drm/i810_context.c [deleted file]
drivers/char/drm/i810_dma.c
drivers/char/drm/i810_drm.h
drivers/char/drm/i810_drv.c
drivers/char/drm/i810_drv.h
drivers/char/drm/init.c [deleted file]
drivers/char/drm/ioctl.c [deleted file]
drivers/char/drm/lists.c [deleted file]
drivers/char/drm/lock.c [deleted file]
drivers/char/drm/memory.c [deleted file]
drivers/char/drm/mga.h [new file with mode: 0644]
drivers/char/drm/mga_bufs.c [deleted file]
drivers/char/drm/mga_context.c [deleted file]
drivers/char/drm/mga_dma.c
drivers/char/drm/mga_drm.h
drivers/char/drm/mga_drv.c
drivers/char/drm/mga_drv.h
drivers/char/drm/mga_state.c
drivers/char/drm/mga_ucode.h [new file with mode: 0644]
drivers/char/drm/mga_warp.c [new file with mode: 0644]
drivers/char/drm/proc.c [deleted file]
drivers/char/drm/r128.h [new file with mode: 0644]
drivers/char/drm/r128_bufs.c [deleted file]
drivers/char/drm/r128_cce.c
drivers/char/drm/r128_context.c [deleted file]
drivers/char/drm/r128_drm.h
drivers/char/drm/r128_drv.c
drivers/char/drm/r128_drv.h
drivers/char/drm/r128_state.c
drivers/char/drm/radeon.h [new file with mode: 0644]
drivers/char/drm/radeon_bufs.c [deleted file]
drivers/char/drm/radeon_context.c [deleted file]
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drv.c
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_state.c
drivers/char/drm/tdfx.h [new file with mode: 0644]
drivers/char/drm/tdfx_context.c [deleted file]
drivers/char/drm/tdfx_drv.c
drivers/char/drm/tdfx_drv.h [deleted file]
drivers/char/drm/vm.c [deleted file]
fs/buffer.c
include/linux/swap.h
mm/page_alloc.c
mm/vmscan.c

index 5745ed7c1cb84326b93d7eb2c8c2daad3f58c4de..587b37d89014cea09a723241983fb82fe3978d4f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 8
-EXTRAVERSION =-pre5
+EXTRAVERSION =-pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
index 6d7649eb041092ea9a684541c092fed079c950f1..4936c6b3f0e59cfafeab02615bc4c5bbab61e212 100644 (file)
@@ -2,14 +2,14 @@
 # drm device configuration
 #
 # This driver provides support for the
-# Direct Rendering Infrastructure (DRI) in XFree86 4.x.
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 #
 
-bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
+bool 'Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)' CONFIG_DRM
 if [ "$CONFIG_DRM" != "n" ]; then
     tristate '  3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX
     tristate '  3dlabs GMX 2000' CONFIG_DRM_GAMMA
-    dep_tristate '  ATI Rage 128' CONFIG_DRM_R128 $CONFIG_AGP
+    tristate '  ATI Rage 128' CONFIG_DRM_R128
     dep_tristate '  ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP
     dep_tristate '  Intel I810' CONFIG_DRM_I810 $CONFIG_AGP
     dep_tristate '  Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP
index eae8e75f0e80961e0db9876dcead7a7e5f4e1e07..97b507eecf5afc50ff7a049fe3ffc828716ec771 100644 (file)
@@ -1,87 +1,30 @@
 #
-# Makefile for the drm device driver.  This driver provides support for
-# the Direct Rendering Infrastructure (DRI) in XFree86 4.x.
-#
+# Makefile for the drm device driver.  This driver provides support for the
+# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 O_TARGET       := drm.o
-
-export-objs     := gamma_drv.o tdfx_drv.o r128_drv.o ffb_drv.o mga_drv.o \
-                  i810_drv.o
-
-# lib-objs are included in every module so that radical changes to the
-# architecture of the DRM support library can be made at a later time.
-#
-# The downside is that each module is larger, and a system that uses
-# more than one module (i.e., a dual-head system) will use more memory
-# (but a system that uses exactly one module will use the same amount of
-# memory).
-#
-# The upside is that if the DRM support library ever becomes insufficient
-# for new families of cards, a new library can be implemented for those new
-# cards without impacting the drivers for the old cards.  This is significant,
-# because testing architectural changes to old cards may be impossible, and
-# may delay the implementation of a better architecture.  We've traded slight
-# memory waste (in the dual-head case) for greatly improved long-term
-# maintainability.
-#
-# NOTE: lib-objs will be eliminated in future versions, thereby
-# eliminating the need to compile the .o files into every module, but
-# for now we still need them.
-#
-
-lib-objs   := init.o memory.o proc.o auth.o context.o drawable.o bufs.o
-lib-objs   += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
-
-ifeq ($(CONFIG_AGP),y)
- lib-objs  += agpsupport.o
-else
- ifeq ($(CONFIG_AGP),m)
-  lib-objs  += agpsupport.o
- endif
-endif
-
-list-multi  := gamma.o tdfx.o r128.o ffb.o mga.o i810.o
-gamma-objs  := gamma_drv.o  gamma_dma.o
-tdfx-objs   := tdfx_drv.o                 tdfx_context.o
-r128-objs   := r128_drv.o   r128_cce.o    r128_context.o r128_bufs.o r128_state.o
-ffb-objs    := ffb_drv.o                  ffb_context.o
-mga-objs    := mga_drv.o    mga_dma.o     mga_context.o  mga_bufs.o  mga_state.o
-i810-objs   := i810_drv.o   i810_dma.o    i810_context.o i810_bufs.o
-radeon-objs := radeon_drv.o radeon_cp.o   radeon_context.o radeon_bufs.o radeon_state.o
+export-objs    := gamma_drv.o tdfx_drv.o r128_drv.o mga_drv.o i810_drv.o \
+                  ffb_drv.o
+list-multi     := gamma.o tdfx.o r128.o mga.o i810.o ffb.o
+
+gamma-objs  := gamma_drv.o gamma_dma.o
+tdfx-objs   := tdfx_drv.o
+r128-objs   := r128_drv.o r128_cce.o r128_state.o
+mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o
+i810-objs   := i810_drv.o i810_dma.o
+radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o
+ffb-objs    := ffb_drv.o ffb_context.o
 
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
-obj-$(CONFIG_DRM_TDFX)  += tdfx.o
-obj-$(CONFIG_DRM_R128)  += r128.o
+obj-$(CONFIG_DRM_TDFX) += tdfx.o
+obj-$(CONFIG_DRM_R128) += r128.o
 obj-$(CONFIG_DRM_RADEON)+= radeon.o
+obj-$(CONFIG_DRM_MGA)  += mga.o
+obj-$(CONFIG_DRM_I810) += i810.o
 obj-$(CONFIG_DRM_FFB)   += ffb.o
-obj-$(CONFIG_DRM_MGA)   += mga.o
-obj-$(CONFIG_DRM_I810)  += i810.o
-
-
-# When linking into the kernel, link the library just once. 
-# If making modules, we include the library into each module
-
-lib-objs-mod := $(patsubst %.o,%-mod.o,$(lib-objs))
-
-ifdef MAKING_MODULES
-  lib = drmlib-mod.a
-else
-  obj-y += drmlib.a
-endif
 
 include $(TOPDIR)/Rules.make
 
-$(patsubst %.o,%.c,$(lib-objs-mod)): 
-       @ln -sf $(subst -mod,,$@) $@
-
-drmlib-mod.a: $(lib-objs-mod)
-       rm -f $@
-       $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-objs-mod)
-
-drmlib.a: $(lib-objs)
-       rm -f $@
-       $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-objs)
-
 gamma.o: $(gamma-objs) $(lib)
        $(LD) -r -o $@ $(gamma-objs) $(lib)
 
diff --git a/drivers/char/drm/agpsupport.c b/drivers/char/drm/agpsupport.c
deleted file mode 100644 (file)
index 9c761dd..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/* agpsupport.c -- 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
- * 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.
- * 
- * Author: Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include <linux/module.h>
-#if LINUX_VERSION_CODE < 0x020400
-#include "agpsupport-pre24.h"
-#else
-#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
-#define DRM_AGP_PUT inter_module_put("drm_agp")
-#endif
-
-static const drm_agp_t *drm_agp = NULL;
-
-int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       agp_kern_info    *kern;
-       drm_agp_info_t   info;
-
-       if (!dev->agp->acquired || !drm_agp->copy_info) return -EINVAL;
-
-       kern                   = &dev->agp->agp_info;
-       info.agp_version_major = kern->version.major;
-       info.agp_version_minor = kern->version.minor;
-       info.mode              = kern->mode;
-       info.aperture_base     = kern->aper_base;
-       info.aperture_size     = kern->aper_size * 1024 * 1024;
-       info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
-       info.memory_used       = kern->current_memory << PAGE_SHIFT;
-       info.id_vendor         = kern->device->vendor;
-       info.id_device         = kern->device->device;
-
-       if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode;
-
-       if (dev->agp->acquired || !drm_agp->acquire) return -EINVAL;
-       if ((retcode = drm_agp->acquire())) return retcode;
-       dev->agp->acquired = 1;
-       return 0;
-}
-
-int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-
-       if (!dev->agp->acquired || !drm_agp->release) return -EINVAL;
-       drm_agp->release();
-       dev->agp->acquired = 0;
-       return 0;
-       
-}
-
-void _drm_agp_release(void)
-{
-       if (drm_agp->release) drm_agp->release();
-}
-
-int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_agp_mode_t   mode;
-
-       if (!dev->agp->acquired || !drm_agp->enable) return -EINVAL;
-
-       if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
-               return -EFAULT;
-       
-       dev->agp->mode    = mode.mode;
-       drm_agp->enable(mode.mode);
-       dev->agp->base    = dev->agp->agp_info.aper_base;
-       dev->agp->enabled = 1;
-       return 0;
-}
-
-int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_agp_buffer_t request;
-       drm_agp_mem_t    *entry;
-       agp_memory       *memory;
-       unsigned long    pages;
-       u32              type;
-       if (!dev->agp->acquired) return -EINVAL;
-       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
-               return -EFAULT;
-       if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
-               return -ENOMEM;
-   
-       memset(entry, 0, sizeof(*entry));
-
-       pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
-       type = (u32) request.type;
-
-       if (!(memory = drm_alloc_agp(pages, type))) {
-               drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               return -ENOMEM;
-       }
-       
-       entry->handle    = (unsigned long)memory->memory;
-       entry->memory    = memory;
-       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;
-
-       request.handle   = entry->handle;
-        request.physical = memory->physical;
-
-       if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
-               dev->agp->memory       = entry->next;
-               dev->agp->memory->prev = NULL;
-               drm_free_agp(memory, pages);
-               drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               return -EFAULT;
-       }
-       return 0;
-}
-
-static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
-                                          unsigned long 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(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t        *priv  = filp->private_data;
-       drm_device_t      *dev   = priv->dev;
-       drm_agp_binding_t request;
-       drm_agp_mem_t     *entry;
-
-       if (!dev->agp->acquired) return -EINVAL;
-       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
-               return -EFAULT;
-       if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
-               return -EINVAL;
-       if (!entry->bound) return -EINVAL;
-       return drm_unbind_agp(entry->memory);
-}
-
-int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t        *priv  = filp->private_data;
-       drm_device_t      *dev   = priv->dev;
-       drm_agp_binding_t request;
-       drm_agp_mem_t     *entry;
-       int               retcode;
-       int               page;
-       
-       if (!dev->agp->acquired || !drm_agp->bind_memory) return -EINVAL;
-       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
-               return -EFAULT;
-       if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
-               return -EINVAL;
-       if (entry->bound) return -EINVAL;
-       page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
-       if ((retcode = drm_bind_agp(entry->memory, page))) return retcode;
-       entry->bound = dev->agp->base + (page << PAGE_SHIFT);
-       DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n", 
-                 dev->agp->base, entry->bound);
-       return 0;
-}
-
-int drm_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_agp_buffer_t request;
-       drm_agp_mem_t    *entry;
-       
-       if (!dev->agp->acquired) return -EINVAL;
-       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
-               return -EFAULT;
-       if (!(entry = drm_agp_lookup_entry(dev, request.handle)))
-               return -EINVAL;
-       if (entry->bound) drm_unbind_agp(entry->memory);
-   
-       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->memory, entry->pages);
-       drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-       return 0;
-}
-
-drm_agp_head_t *drm_agp_init(void)
-{
-       drm_agp_head_t *head         = NULL;
-
-       drm_agp = DRM_AGP_GET;
-       if (drm_agp) {
-               if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
-                       return NULL;
-               memset((void *)head, 0, sizeof(*head));
-               drm_agp->copy_info(&head->agp_info);
-               if (head->agp_info.chipset == NOT_SUPPORTED) {
-                       drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
-                       return NULL;
-               }
-               head->memory = NULL;
-               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;
-
-#if LINUX_VERSION_CODE >= 0x020400
-               case INTEL_I840:        head->chipset = "Intel i840";    break;
-#endif
-
-               case VIA_GENERIC:       head->chipset = "VIA";           break;
-               case VIA_VP3:           head->chipset = "VIA VP3";       break;
-               case VIA_MVP3:          head->chipset = "VIA MVP3";      break;
-
-#if LINUX_VERSION_CODE >= 0x020400
-               case VIA_MVP4:          head->chipset = "VIA MVP4";      break;
-               case VIA_APOLLO_KX133:  head->chipset = "VIA Apollo KX133"; 
-                       break;
-               case VIA_APOLLO_KT133:  head->chipset = "VIA Apollo KT133"; 
-                       break;
-#endif
-
-               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;
-               case ALI_M1621:         head->chipset = "ALi M1621";     break;
-               case ALI_M1631:         head->chipset = "ALi M1631";     break;
-               case ALI_M1632:         head->chipset = "ALi M1632";     break;
-               case ALI_M1641:         head->chipset = "ALi M1641";     break;
-               case ALI_M1647:         head->chipset = "ALi M1647";     break;
-               case ALI_M1651:         head->chipset = "ALi M1651";     break;
-               case SVWRKS_GENERIC:    head->chipset = "Serverworks Generic";
-                       break;
-               case SVWRKS_HE:         head->chipset = "Serverworks HE"; break;
-               case SVWRKS_LE:         head->chipset = "Serverworks LE"; break;
-
-               default:                head->chipset = "Unknown";       break;
-               }
-               DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
-                        head->agp_info.version.major,
-                        head->agp_info.version.minor,
-                        head->chipset,
-                        head->agp_info.aper_base,
-                        head->agp_info.aper_size);
-       }
-       return head;
-}
-
-void drm_agp_uninit(void)
-{
-       DRM_AGP_PUT;
-       drm_agp = NULL;
-}
-
-agp_memory *drm_agp_allocate_memory(size_t pages, u32 type)
-{
-       if (!drm_agp->allocate_memory) return NULL;
-       return drm_agp->allocate_memory(pages, type);
-}
-
-int drm_agp_free_memory(agp_memory *handle)
-{
-       if (!handle || !drm_agp->free_memory) return 0;
-       drm_agp->free_memory(handle);
-       return 1;
-}
-
-int drm_agp_bind_memory(agp_memory *handle, off_t start)
-{
-       if (!handle || !drm_agp->bind_memory) return -EINVAL;
-       return drm_agp->bind_memory(handle, start);
-}
-
-int drm_agp_unbind_memory(agp_memory *handle)
-{
-       if (!handle || !drm_agp->unbind_memory) return -EINVAL;
-       return drm_agp->unbind_memory(handle);
-}
diff --git a/drivers/char/drm/ati_pcigart.h b/drivers/char/drm/ati_pcigart.h
new file mode 100644 (file)
index 0000000..93c5148
--- /dev/null
@@ -0,0 +1,138 @@
+/* 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>
+ */
+
+#define __NO_VERSION__
+#include "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 */
+
+static unsigned long DRM(ati_alloc_pcigart_table)( void )
+{
+       unsigned long address;
+       struct page *page;
+       int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
+       if ( address == 0UL ) {
+               return 0;
+       }
+
+       page = virt_to_page( address );
+
+       for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+               atomic_inc( &page->count );
+               SetPageReserved( page );
+       }
+
+       DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
+       return address;
+}
+
+static void DRM(ati_free_pcigart_table)( unsigned long address )
+{
+       struct page *page;
+       int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       if ( !address ) return;
+
+       page = virt_to_page( address );
+
+       for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
+               atomic_dec( &page->count );
+               ClearPageReserved( page );
+       }
+
+       free_pages( address, ATI_PCIGART_TABLE_ORDER );
+}
+
+unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
+{
+       drm_sg_mem_t *entry = dev->sg;
+       unsigned long address;
+       unsigned long pages;
+       u32 *pci_gart, page_base;
+       int i, j;
+
+       if ( !entry ) {
+               DRM_ERROR( "no scatter/gather memory!\n" );
+               return 0;
+       }
+
+       address = DRM(ati_alloc_pcigart_table)();
+       if ( !address ) {
+               DRM_ERROR( "cannot allocate PCI GART page!\n" );
+               return 0;
+       }
+
+       pci_gart = (u32 *)address;
+
+       pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+               ? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+       memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
+
+       for ( i = 0 ; i < pages ; i++ ) {
+               page_base = virt_to_bus( entry->pagelist[i]->virtual );
+               for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+                       *pci_gart++ = cpu_to_le32( page_base );
+                       page_base += ATI_PCIGART_PAGE_SIZE;
+               }
+       }
+
+#if __i386__
+       asm volatile ( "wbinvd" ::: "memory" );
+#else
+       mb();
+#endif
+
+       return address;
+}
+
+int DRM(ati_pcigart_cleanup)( unsigned long address )
+{
+
+       if ( address ) {
+               DRM(ati_free_pcigart_table)( address );
+       }
+
+       return 0;
+}
diff --git a/drivers/char/drm/auth.c b/drivers/char/drm/auth.c
deleted file mode 100644 (file)
index 80bb4b6..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* auth.c -- IOCTLs for authentication -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-static int drm_hash_magic(drm_magic_t magic)
-{
-       return magic & (DRM_HASH_SIZE-1);
-}
-
-static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
-{
-       drm_file_t        *retval = NULL;
-       drm_magic_entry_t *pt;
-       int               hash    = drm_hash_magic(magic);
-
-       down(&dev->struct_sem);
-       for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
-               if (pt->magic == magic) {
-                       retval = pt->priv;
-                       break;
-               }
-       }
-       up(&dev->struct_sem);
-       return retval;
-}
-
-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_alloc(sizeof(*entry), DRM_MEM_MAGIC);
-       if (!entry) return -ENOMEM;
-       entry->magic = magic;
-       entry->priv  = priv;
-       entry->next  = NULL;
-
-       down(&dev->struct_sem);
-       if (dev->magiclist[hash].tail) {
-               dev->magiclist[hash].tail->next = entry;
-               dev->magiclist[hash].tail       = entry;
-       } else {
-               dev->magiclist[hash].head       = entry;
-               dev->magiclist[hash].tail       = entry;
-       }
-       up(&dev->struct_sem);
-       
-       return 0;
-}
-
-int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
-{
-       drm_magic_entry_t *prev = NULL;
-       drm_magic_entry_t *pt;
-       int               hash;
-       
-       DRM_DEBUG("%d\n", magic);
-       hash = drm_hash_magic(magic);
-       
-       down(&dev->struct_sem);
-       for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
-               if (pt->magic == magic) {
-                       if (dev->magiclist[hash].head == pt) {
-                               dev->magiclist[hash].head = pt->next;
-                       }
-                       if (dev->magiclist[hash].tail == pt) {
-                               dev->magiclist[hash].tail = prev;
-                       }
-                       if (prev) {
-                               prev->next = pt->next;
-                       }
-                       up(&dev->struct_sem);
-                       return 0;
-               }
-       }
-       up(&dev->struct_sem);
-
-       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-       
-       return -EINVAL;
-}
-
-int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       static drm_magic_t sequence = 0;
-       static spinlock_t  lock     = SPIN_LOCK_UNLOCKED;
-       drm_file_t         *priv    = filp->private_data;
-       drm_device_t       *dev     = priv->dev;
-       drm_auth_t         auth;
-
-                               /* Find unique magic */
-       if (priv->magic) {
-               auth.magic = priv->magic;
-       } else {
-               do {
-                       spin_lock(&lock);
-                       if (!sequence) ++sequence; /* reserve 0 */
-                       auth.magic = sequence++;
-                       spin_unlock(&lock);
-               } while (drm_find_file(dev, auth.magic));
-               priv->magic = auth.magic;
-               drm_add_magic(dev, priv, auth.magic);
-       }
-       
-       DRM_DEBUG("%u\n", auth.magic);
-       if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t         *priv    = filp->private_data;
-       drm_device_t       *dev     = priv->dev;
-       drm_auth_t         auth;
-       drm_file_t         *file;
-
-       if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth)))
-               return -EFAULT;
-       DRM_DEBUG("%u\n", auth.magic);
-       if ((file = drm_find_file(dev, auth.magic))) {
-               file->authenticated = 1;
-               drm_remove_magic(dev, auth.magic);
-               return 0;
-       }
-       return -EINVAL;
-}
diff --git a/drivers/char/drm/bufs.c b/drivers/char/drm/bufs.c
deleted file mode 100644 (file)
index dae94d4..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-/* bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include <linux/config.h>
-#include "drmP.h"
-#include "linux/un.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;
-}
-
-int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_map_t       *map;
-       
-       if (!(filp->f_mode & 3)) return -EACCES; /* Require read/write */
-
-       map          = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
-       if (!map) return -ENOMEM;
-       if (copy_from_user(map, (drm_map_t *)arg, sizeof(*map))) {
-               drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               return -EFAULT;
-       }
-
-       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 -EINVAL;
-       }
-       map->mtrr   = -1;
-       map->handle = 0;
-
-       switch (map->type) {
-       case _DRM_REGISTERS:
-       case _DRM_FRAME_BUFFER:
-#ifndef __sparc__
-               if (map->offset + map->size < map->offset
-                   || map->offset < virt_to_phys(high_memory)) {
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-                       return -EINVAL;
-               }
-#endif
-#ifdef CONFIG_MTRR
-               if (map->type == _DRM_FRAME_BUFFER
-                   || (map->flags & _DRM_WRITE_COMBINING)) {
-                       map->mtrr = mtrr_add(map->offset, map->size,
-                                            MTRR_TYPE_WRCOMB, 1);
-               }
-#endif
-               map->handle = drm_ioremap(map->offset, map->size);
-               break;
-                       
-
-       case _DRM_SHM:
-               map->handle = (void *)drm_alloc_pages(drm_order(map->size)
-                                                     - PAGE_SHIFT,
-                                                     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 -ENOMEM;
-               }
-               map->offset = (unsigned long)map->handle;
-               if (map->flags & _DRM_CONTAINS_LOCK) {
-                       dev->lock.hw_lock = map->handle; /* Pointer to lock */
-               }
-               break;
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       case _DRM_AGP:
-               map->offset = map->offset + dev->agp->base;
-               break;
-#endif
-       default:
-               drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               return -EINVAL;
-       }
-
-       down(&dev->struct_sem);
-       if (dev->maplist) {
-               ++dev->map_count;
-               dev->maplist = drm_realloc(dev->maplist,
-                                          (dev->map_count-1)
-                                          * sizeof(*dev->maplist),
-                                          dev->map_count
-                                          * sizeof(*dev->maplist),
-                                          DRM_MEM_MAPS);
-       } else {
-               dev->map_count = 1;
-               dev->maplist = drm_alloc(dev->map_count*sizeof(*dev->maplist),
-                                        DRM_MEM_MAPS);
-       }
-       dev->maplist[dev->map_count-1] = map;
-       up(&dev->struct_sem);
-
-       if (copy_to_user((drm_map_t *)arg, map, sizeof(*map)))
-               return -EFAULT;
-       if (map->type != _DRM_SHM) {
-               if (copy_to_user(&((drm_map_t *)arg)->handle,
-                                &map->offset,
-                                sizeof(map->offset)))
-                       return -EFAULT;
-       }               
-       return 0;
-}
-
-int drm_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_desc_t   request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       count      = request.count;
-       order      = drm_order(request.size);
-       size       = 1 << order;
-       
-       DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
-                 request.count, request.size, size, order, dev->queue_count);
-
-       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
-       page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-       total      = PAGE_SIZE << page_order;
-
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-       
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-       
-       if(count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               return -EINVAL;
-       }
-       
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -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);
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM;
-       }
-       memset(entry->seglist, 0, count * sizeof(*entry->seglist));
-
-       dma->pagelist = drm_realloc(dma->pagelist,
-                                   dma->page_count * sizeof(*dma->pagelist),
-                                   (dma->page_count + (count << page_order))
-                                   * sizeof(*dma->pagelist),
-                                   DRM_MEM_PAGES);
-       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) {
-               if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) 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->waiting = 0;
-                       buf->pending = 0;
-                       init_waitqueue_head(&buf->dma_wait);
-                       buf->pid     = 0;
-#if DRM_DMA_HISTOGRAM
-                       buf->time_queued     = 0;
-                       buf->time_dispatched = 0;
-                       buf->time_completed  = 0;
-                       buf->time_freed      = 0;
-#endif
-                       DRM_DEBUG("buffer %d @ %p\n",
-                                 entry->buf_count, buf->address);
-               }
-               byte_count += PAGE_SIZE << page_order;
-       }
-
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
-       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_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-       
-       up(&dev->struct_sem);
-
-       request.count = entry->buf_count;
-       request.size  = size;
-
-       if (copy_to_user((drm_buf_desc_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-       
-       atomic_dec(&dev->buf_alloc);
-       return 0;
-}
-
-int drm_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_info_t   request;
-       int              i;
-       int              count;
-
-       if (!dma) return -EINVAL;
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_info_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       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) {
-                               if (copy_to_user(&request.list[count].count,
-                                                &dma->bufs[i].buf_count,
-                                                sizeof(dma->bufs[0]
-                                                       .buf_count)) ||
-                                   copy_to_user(&request.list[count].size,
-                                                &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size)) ||
-                                   copy_to_user(&request.list[count].low_mark,
-                                                &dma->bufs[i]
-                                                .freelist.low_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.low_mark)) ||
-                                   copy_to_user(&request.list[count]
-                                                .high_mark,
-                                                &dma->bufs[i]
-                                                .freelist.high_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.high_mark)))
-                                       return -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;
-
-       if (copy_to_user((drm_buf_info_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-       
-       return 0;
-}
-
-int drm_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_desc_t   request;
-       int              order;
-       drm_buf_entry_t  *entry;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       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 -EINVAL;
-       entry = &dma->bufs[order];
-
-       if (request.low_mark < 0 || request.low_mark > entry->buf_count)
-               return -EINVAL;
-       if (request.high_mark < 0 || request.high_mark > entry->buf_count)
-               return -EINVAL;
-
-       entry->freelist.low_mark  = request.low_mark;
-       entry->freelist.high_mark = request.high_mark;
-       
-       return 0;
-}
-
-int drm_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_free_t   request;
-       int              i;
-       int              idx;
-       drm_buf_t        *buf;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_free_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       DRM_DEBUG("%d\n", request.count);
-       for (i = 0; i < request.count; i++) {
-               if (copy_from_user(&idx,
-                                  &request.list[i],
-                                  sizeof(idx)))
-                       return -EFAULT;
-               if (idx < 0 || idx >= dma->buf_count) {
-                       DRM_ERROR("Index %d (of %d max)\n",
-                                 idx, dma->buf_count - 1);
-                       return -EINVAL;
-               }
-               buf = dma->buflist[idx];
-               if (buf->pid != current->pid) {
-                       DRM_ERROR("Process %d freeing buffer owned by %d\n",
-                                 current->pid, buf->pid);
-                       return -EINVAL;
-               }
-               drm_free_buffer(dev, buf);
-       }
-       
-       return 0;
-}
-
-int drm_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       int              retcode = 0;
-       const int        zero    = 0;
-       unsigned long    virtual;
-       unsigned long    address;
-       drm_buf_map_t    request;
-       int              i;
-
-       if (!dma) return -EINVAL;
-       
-       DRM_DEBUG("\n");
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_map_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       if (request.count >= dma->buf_count) {
-               down_write(&current->mm->mmap_sem);
-               virtual = do_mmap(filp, 0, dma->byte_count,
-                                 PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-               up_write(&current->mm->mmap_sem);
-               if (virtual > -1024UL) {
-                               /* Real error */
-                       retcode = (signed long)virtual;
-                       goto done;
-               }
-               request.virtual = (void *)virtual;
-
-               for (i = 0; i < dma->buf_count; i++) {
-                       if (copy_to_user(&request.list[i].idx,
-                                        &dma->buflist[i]->idx,
-                                        sizeof(request.list[0].idx))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].total,
-                                        &dma->buflist[i]->total,
-                                        sizeof(request.list[0].total))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].used,
-                                        &zero,
-                                        sizeof(zero))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       address = virtual + dma->buflist[i]->offset;
-                       if (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);
-
-       if (copy_to_user((drm_buf_map_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-
-       return retcode;
-}
diff --git a/drivers/char/drm/context.c b/drivers/char/drm/context.c
deleted file mode 100644 (file)
index aa26073..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/* context.c -- IOCTLs for contexts and DMA queues -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
-{
-       DRM_DEBUG("\n");
-       
-       if (atomic_read(&q->use_count) != 1
-           || atomic_read(&q->finalization)
-           || atomic_read(&q->block_count)) {
-               DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
-                         atomic_read(&q->use_count),
-                         atomic_read(&q->finalization),
-                         atomic_read(&q->block_count));
-       }
-                 
-       atomic_set(&q->finalization,  0);
-       atomic_set(&q->block_count,   0);
-       atomic_set(&q->block_read,    0);
-       atomic_set(&q->block_write,   0);
-       atomic_set(&q->total_queued,  0);
-       atomic_set(&q->total_flushed, 0);
-       atomic_set(&q->total_locks,   0);
-
-       init_waitqueue_head(&q->write_queue);
-       init_waitqueue_head(&q->read_queue);
-       init_waitqueue_head(&q->flush_queue);
-
-       q->flags = ctx->flags;
-
-       drm_waitlist_create(&q->waitlist, dev->dma->buf_count);
-
-       return 0;
-}
-
-
-/* drm_alloc_queue:
-PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
-       disappear (so all deallocation must be done after IOCTLs are off)
-     2) dev->queue_count < dev->queue_slots
-     3) dev->queuelist[i].use_count == 0 and
-       dev->queuelist[i].finalization == 0 if i not in use 
-POST: 1) dev->queuelist[i].use_count == 1
-      2) dev->queue_count < dev->queue_slots */
-               
-static int drm_alloc_queue(drm_device_t *dev)
-{
-       int         i;
-       drm_queue_t *queue;
-       int         oldslots;
-       int         newslots;
-                               /* Check for a free queue */
-       for (i = 0; i < dev->queue_count; i++) {
-               atomic_inc(&dev->queuelist[i]->use_count);
-               if (atomic_read(&dev->queuelist[i]->use_count) == 1
-                   && !atomic_read(&dev->queuelist[i]->finalization)) {
-                       DRM_DEBUG("%d (free)\n", i);
-                       return i;
-               }
-               atomic_dec(&dev->queuelist[i]->use_count);
-       }
-                               /* Allocate a new queue */
-       
-       queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
-       if(queue == NULL)
-               return -ENOMEM; 
-
-       memset(queue, 0, sizeof(*queue));
-       down(&dev->struct_sem);
-       atomic_set(&queue->use_count, 1);
-       
-       ++dev->queue_count;
-       if (dev->queue_count >= dev->queue_slots) {
-               oldslots = dev->queue_slots * sizeof(*dev->queuelist);
-               if (!dev->queue_slots) dev->queue_slots = 1;
-               dev->queue_slots *= 2;
-               newslots = dev->queue_slots * sizeof(*dev->queuelist);
-
-               dev->queuelist = drm_realloc(dev->queuelist,
-                                            oldslots,
-                                            newslots,
-                                            DRM_MEM_QUEUES);
-               if (!dev->queuelist) {
-                       up(&dev->struct_sem);
-                       DRM_DEBUG("out of memory\n");
-                       return -ENOMEM;
-               }
-       }
-       dev->queuelist[dev->queue_count-1] = queue;
-       
-       up(&dev->struct_sem);
-       DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
-       return dev->queue_count - 1;
-}
-
-int drm_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i],
-                                        &i,
-                                        sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-
-int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Init kernel's context and get a new one. */
-               drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
-               ctx.handle = drm_alloc_queue(dev);
-       }
-       drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
-       DRM_DEBUG("%d\n", ctx.handle);
-       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-       drm_queue_t     *q;
-               
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       
-       DRM_DEBUG("%d\n", ctx.handle);
-       
-       if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
-       q = dev->queuelist[ctx.handle];
-       
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) == 1) {
-                               /* No longer in use */
-               atomic_dec(&q->use_count);
-               return -EINVAL;
-       }
-
-       if (DRM_BUFCOUNT(&q->waitlist)) {
-               atomic_dec(&q->use_count);
-               return -EBUSY;
-       }
-       
-       q->flags = ctx.flags;
-       
-       atomic_dec(&q->use_count);
-       return 0;
-}
-
-int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-       drm_queue_t     *q;
-               
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       
-       DRM_DEBUG("%d\n", ctx.handle);
-       
-       if (ctx.handle >= dev->queue_count) return -EINVAL;
-       q = dev->queuelist[ctx.handle];
-       
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) == 1) {
-                               /* No longer in use */
-               atomic_dec(&q->use_count);
-               return -EINVAL;
-       }
-       
-       ctx.flags = q->flags;
-       atomic_dec(&q->use_count);
-       
-       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       
-       return 0;
-}
-
-int drm_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return drm_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int drm_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       drm_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int drm_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-       drm_queue_t     *q;
-       drm_buf_t       *buf;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       
-       if (ctx.handle >= dev->queue_count) return -EINVAL;
-       q = dev->queuelist[ctx.handle];
-       
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) == 1) {
-                               /* No longer in use */
-               atomic_dec(&q->use_count);
-               return -EINVAL;
-       }
-       
-       atomic_inc(&q->finalization); /* Mark queue in finalization state */
-       atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
-                                        finalization) */
-
-       while (test_and_set_bit(0, &dev->interrupt_flag)) {
-               schedule();
-               if (signal_pending(current)) {
-                       clear_bit(0, &dev->interrupt_flag);
-                       return -EINTR;
-               }
-       }
-                               /* Remove queued buffers */
-       while ((buf = drm_waitlist_get(&q->waitlist))) {
-               drm_free_buffer(dev, buf);
-       }
-       clear_bit(0, &dev->interrupt_flag);
-       
-                               /* Wakeup blocked processes */
-       wake_up_interruptible(&q->read_queue);
-       wake_up_interruptible(&q->write_queue);
-       wake_up_interruptible(&q->flush_queue);
-       
-                               /* Finalization over.  Queue is made
-                                  available when both use_count and
-                                  finalization become 0, which won't
-                                  happen until all the waiting processes
-                                  stop waiting. */
-       atomic_dec(&q->finalization);
-       return 0;
-}
diff --git a/drivers/char/drm/ctxbitmap.c b/drivers/char/drm/ctxbitmap.c
deleted file mode 100644 (file)
index 6155059..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ctxbitmap.c -- Context bitmap management -*- linux-c -*-
- * Created: Thu Jan 6 03:56:42 2000 by jhartmann@precisioninsight.com
- * 
- * Copyright 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
- * 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.
- *
- * Author: Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle)
-{
-       if (ctx_handle < 0) goto failed;
-
-       if (ctx_handle < DRM_MAX_CTXBITMAP) {
-               clear_bit(ctx_handle, dev->ctx_bitmap);
-               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;
-
-       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);
-               return bit;
-       }
-       return -1;
-}
-
-int drm_ctxbitmap_init(drm_device_t *dev)
-{
-       int i;
-       int temp;
-
-       dev->ctx_bitmap = (unsigned long *) drm_alloc(PAGE_SIZE, 
-                                                     DRM_MEM_CTXBITMAP);
-       if(dev->ctx_bitmap == NULL) {
-               return -ENOMEM;
-       }
-       memset((void *) dev->ctx_bitmap, 0, PAGE_SIZE);
-       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_free((void *)dev->ctx_bitmap, PAGE_SIZE,
-                DRM_MEM_CTXBITMAP);
-}
-
diff --git a/drivers/char/drm/dma.c b/drivers/char/drm/dma.c
deleted file mode 100644 (file)
index f6c532d..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-/* dma.c -- DMA IOCTL and function support -*- linux-c -*-
- * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.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
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinuxa.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-#include <linux/interrupt.h>   /* For task queue support */
-
-void drm_dma_setup(drm_device_t *dev)
-{
-       int i;
-       
-       if (!(dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER))) {
-                printk(KERN_ERR "drm_dma_setup: can't drm_alloc dev->dma");
-                return;
-        }       
-       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]));
-}
-
-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_pages(dma->bufs[i].seglist[j],
-                                              dma->bufs[i].page_order,
-                                              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);
-                       drm_freelist_destroy(&dma->bufs[i].freelist);
-               }
-       }
-       
-       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;
-}
-
-#if DRM_DMA_HISTOGRAM
-/* This is slow, but is useful for debugging. */
-int drm_histogram_slot(unsigned long count)
-{
-       int value = DRM_DMA_HISTOGRAM_INITIAL;
-       int slot;
-
-       for (slot = 0;
-            slot < DRM_DMA_HISTOGRAM_SLOTS;
-            ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) {
-               if (count < value) return slot;
-       }
-       return DRM_DMA_HISTOGRAM_SLOTS - 1;
-}
-
-void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
-{
-       cycles_t queued_to_dispatched;
-       cycles_t dispatched_to_completed;
-       cycles_t completed_to_freed;
-       int      q2d, d2c, c2f, q2c, q2f;
-       
-       if (buf->time_queued) {
-               queued_to_dispatched    = (buf->time_dispatched
-                                          - buf->time_queued);
-               dispatched_to_completed = (buf->time_completed
-                                          - buf->time_dispatched);
-               completed_to_freed      = (buf->time_freed
-                                          - buf->time_completed);
-
-               q2d = drm_histogram_slot(queued_to_dispatched);
-               d2c = drm_histogram_slot(dispatched_to_completed);
-               c2f = drm_histogram_slot(completed_to_freed);
-
-               q2c = drm_histogram_slot(queued_to_dispatched
-                                        + dispatched_to_completed);
-               q2f = drm_histogram_slot(queued_to_dispatched
-                                        + dispatched_to_completed
-                                        + completed_to_freed);
-               
-               atomic_inc(&dev->histo.total);
-               atomic_inc(&dev->histo.queued_to_dispatched[q2d]);
-               atomic_inc(&dev->histo.dispatched_to_completed[d2c]);
-               atomic_inc(&dev->histo.completed_to_freed[c2f]);
-               
-               atomic_inc(&dev->histo.queued_to_completed[q2c]);
-               atomic_inc(&dev->histo.queued_to_freed[q2f]);
-
-       }
-       buf->time_queued     = 0;
-       buf->time_dispatched = 0;
-       buf->time_completed  = 0;
-       buf->time_freed      = 0;
-}
-#endif
-
-void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
-{
-       drm_device_dma_t *dma = dev->dma;
-
-       if (!buf) return;
-       
-       buf->waiting  = 0;
-       buf->pending  = 0;
-       buf->pid      = 0;
-       buf->used     = 0;
-#if DRM_DMA_HISTOGRAM
-       buf->time_completed = get_cycles();
-#endif
-       if (waitqueue_active(&buf->dma_wait)) {
-               wake_up_interruptible(&buf->dma_wait);
-       } else {
-                               /* If processes are waiting, the last one
-                                  to wake will put the buffer on the free
-                                  list.  If no processes are waiting, we
-                                  put the buffer on the freelist here. */
-               drm_freelist_put(dev, &dma->bufs[buf->order].freelist, buf);
-       }
-}
-
-void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
-{
-       drm_device_dma_t *dma = dev->dma;
-       int              i;
-
-       if (!dma) return;
-       for (i = 0; i < dma->buf_count; i++) {
-               if (dma->buflist[i]->pid == pid) {
-                       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;
-                       }
-               }
-       }
-}
-
-int drm_context_switch(drm_device_t *dev, int old, int new)
-{
-       char        buf[64];
-       drm_queue_t *q;
-
-       atomic_inc(&dev->total_ctx);
-
-       if (test_and_set_bit(0, &dev->context_flag)) {
-               DRM_ERROR("Reentering -- FIXME\n");
-               return -EBUSY;
-       }
-
-#if DRM_DMA_HISTOGRAM
-       dev->ctx_start = get_cycles();
-#endif
-       
-       DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-       if (new >= dev->queue_count) {
-               clear_bit(0, &dev->context_flag);
-               return -EINVAL;
-       }
-
-       if (new == dev->last_context) {
-               clear_bit(0, &dev->context_flag);
-               return 0;
-       }
-       
-       q = dev->queuelist[new];
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) == 1) {
-               atomic_dec(&q->use_count);
-               clear_bit(0, &dev->context_flag);
-               return -EINVAL;
-       }
-
-       if (drm_flags & DRM_FLAG_NOCTX) {
-               drm_context_switch_complete(dev, new);
-       } else {
-               sprintf(buf, "C %d %d\n", old, new);
-               drm_write_string(dev, buf);
-       }
-       
-       atomic_dec(&q->use_count);
-       
-       return 0;
-}
-
-int drm_context_switch_complete(drm_device_t *dev, int new)
-{
-       drm_device_dma_t *dma = dev->dma;
-       
-       dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-       dev->last_switch  = jiffies;
-       
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("Lock isn't held after context switch\n");
-       }
-
-       if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("Cannot free lock\n");
-               }
-       }
-       
-#if DRM_DMA_HISTOGRAM
-       atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                     - dev->ctx_start)]);
-                  
-#endif
-       clear_bit(0, &dev->context_flag);
-       wake_up_interruptible(&dev->context_wait);
-       
-       return 0;
-}
-
-void drm_clear_next_buffer(drm_device_t *dev)
-{
-       drm_device_dma_t *dma = dev->dma;
-       
-       dma->next_buffer = NULL;
-       if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) {
-               wake_up_interruptible(&dma->next_queue->flush_queue);
-       }
-       dma->next_queue  = NULL;
-}
-
-
-int drm_select_queue(drm_device_t *dev, void (*wrapper)(unsigned long))
-{
-       int        i;
-       int        candidate = -1;
-       int        j         = jiffies;
-
-       if (!dev) {
-               DRM_ERROR("No device\n");
-               return -1;
-       }
-       if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) {
-                               /* This only happens between the time the
-                                  interrupt is initialized and the time
-                                  the queues are initialized. */
-               return -1;
-       }
-
-                               /* Doing "while locked" DMA? */
-       if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
-               return DRM_KERNEL_CONTEXT;
-       }
-
-                               /* If there are buffers on the last_context
-                                  queue, and we have not been executing
-                                  this context very long, continue to
-                                  execute this context. */
-       if (dev->last_switch <= j
-           && dev->last_switch + DRM_TIME_SLICE > j
-           && DRM_WAITCOUNT(dev, dev->last_context)) {
-               return dev->last_context;
-       }
-
-                               /* Otherwise, find a candidate */
-       for (i = dev->last_checked + 1; i < dev->queue_count; i++) {
-               if (DRM_WAITCOUNT(dev, i)) {
-                       candidate = dev->last_checked = i;
-                       break;
-               }
-       }
-
-       if (candidate < 0) {
-               for (i = 0; i < dev->queue_count; i++) {
-                       if (DRM_WAITCOUNT(dev, i)) {
-                               candidate = dev->last_checked = i;
-                               break;
-                       }
-               }
-       }
-
-       if (wrapper
-           && candidate >= 0
-           && candidate != dev->last_context
-           && dev->last_switch <= j
-           && dev->last_switch + DRM_TIME_SLICE > j) {
-               if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) {
-                       del_timer(&dev->timer);
-                       dev->timer.function = wrapper;
-                       dev->timer.data     = (unsigned long)dev;
-                       dev->timer.expires  = dev->last_switch+DRM_TIME_SLICE;
-                       add_timer(&dev->timer);
-               }
-               return -1;
-       }
-
-       return candidate;
-}
-
-
-int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
-{
-       int               i;
-       drm_queue_t       *q;
-       drm_buf_t         *buf;
-       int               idx;
-       int               while_locked = 0;
-       drm_device_dma_t  *dma = dev->dma;
-       DECLARE_WAITQUEUE(entry, current);
-
-       DRM_DEBUG("%d\n", d->send_count);
-
-       if (d->flags & _DRM_DMA_WHILE_LOCKED) {
-               int context = dev->lock.hw_lock->lock;
-               
-               if (!_DRM_LOCK_IS_HELD(context)) {
-                       DRM_ERROR("No lock held during \"while locked\""
-                                 " request\n");
-                       return -EINVAL;
-               }
-               if (d->context != _DRM_LOCKING_CONTEXT(context)
-                   && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) {
-                       DRM_ERROR("Lock held by %d while %d makes"
-                                 " \"while locked\" request\n",
-                                 _DRM_LOCKING_CONTEXT(context),
-                                 d->context);
-                       return -EINVAL;
-               }
-               q = dev->queuelist[DRM_KERNEL_CONTEXT];
-               while_locked = 1;
-       } else {
-               q = dev->queuelist[d->context];
-       }
-
-
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->block_write)) {
-               add_wait_queue(&q->write_queue, &entry);
-               atomic_inc(&q->block_count);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!atomic_read(&q->block_write)) break;
-                       schedule();
-                       if (signal_pending(current)) {
-                               atomic_dec(&q->use_count);
-                               remove_wait_queue(&q->write_queue, &entry);
-                               return -EINTR;
-                       }
-               }
-               atomic_dec(&q->block_count);
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&q->write_queue, &entry);
-       }
-       
-       for (i = 0; i < d->send_count; i++) {
-               idx = d->send_indices[i];
-               if (idx < 0 || idx >= dma->buf_count) {
-                       atomic_dec(&q->use_count);
-                       DRM_ERROR("Index %d (of %d max)\n",
-                                 d->send_indices[i], dma->buf_count - 1);
-                       return -EINVAL;
-               }
-               buf = dma->buflist[ idx ];
-               if (buf->pid != current->pid) {
-                       atomic_dec(&q->use_count);
-                       DRM_ERROR("Process %d using buffer owned by %d\n",
-                                 current->pid, buf->pid);
-                       return -EINVAL;
-               }
-               if (buf->list != DRM_LIST_NONE) {
-                       atomic_dec(&q->use_count);
-                       DRM_ERROR("Process %d using buffer %d on list %d\n",
-                                 current->pid, buf->idx, buf->list);
-               }
-               buf->used         = d->send_sizes[i];
-               buf->while_locked = while_locked;
-               buf->context      = d->context;
-               if (!buf->used) {
-                       DRM_ERROR("Queueing 0 length buffer\n");
-               }
-               if (buf->pending) {
-                       atomic_dec(&q->use_count);
-                       DRM_ERROR("Queueing pending buffer:"
-                                 " buffer %d, offset %d\n",
-                                 d->send_indices[i], i);
-                       return -EINVAL;
-               }
-               if (buf->waiting) {
-                       atomic_dec(&q->use_count);
-                       DRM_ERROR("Queueing waiting buffer:"
-                                 " buffer %d, offset %d\n",
-                                 d->send_indices[i], i);
-                       return -EINVAL;
-               }
-               buf->waiting = 1;
-               if (atomic_read(&q->use_count) == 1
-                   || atomic_read(&q->finalization)) {
-                       drm_free_buffer(dev, buf);
-               } else {
-                       drm_waitlist_put(&q->waitlist, buf);
-                       atomic_inc(&q->total_queued);
-               }
-       }
-       atomic_dec(&q->use_count);
-       
-       return 0;
-}
-
-static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *d,
-                                       int order)
-{
-       int               i;
-       drm_buf_t         *buf;
-       drm_device_dma_t  *dma = dev->dma;
-       
-       for (i = d->granted_count; i < d->request_count; i++) {
-               buf = drm_freelist_get(&dma->bufs[order].freelist,
-                                      d->flags & _DRM_DMA_WAIT);
-               if (!buf) break;
-               if (buf->pending || buf->waiting) {
-                       DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n",
-                                 buf->idx,
-                                 buf->pid,
-                                 buf->waiting,
-                                 buf->pending);
-               }
-               buf->pid     = current->pid;
-               if (copy_to_user(&d->request_indices[i],
-                                &buf->idx,
-                                sizeof(buf->idx)))
-                       return -EFAULT;
-
-               if (copy_to_user(&d->request_sizes[i],
-                                &buf->total,
-                                sizeof(buf->total)))
-                       return -EFAULT;
-
-               ++d->granted_count;
-       }
-       return 0;
-}
-
-
-int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
-{
-       int               order;
-       int               retcode = 0;
-       int               tmp_order;
-       
-       order = drm_order(dma->request_size);
-
-       dma->granted_count = 0;
-       retcode            = drm_dma_get_buffers_of_order(dev, dma, order);
-
-       if (dma->granted_count < dma->request_count
-           && (dma->flags & _DRM_DMA_SMALLER_OK)) {
-               for (tmp_order = order - 1;
-                    !retcode
-                            && dma->granted_count < dma->request_count
-                            && tmp_order >= DRM_MIN_ORDER;
-                    --tmp_order) {
-                       
-                       retcode = drm_dma_get_buffers_of_order(dev, dma,
-                                                              tmp_order);
-               }
-       }
-
-       if (dma->granted_count < dma->request_count
-           && (dma->flags & _DRM_DMA_LARGER_OK)) {
-               for (tmp_order = order + 1;
-                    !retcode
-                            && dma->granted_count < dma->request_count
-                            && tmp_order <= DRM_MAX_ORDER;
-                    ++tmp_order) {
-                       
-                       retcode = drm_dma_get_buffers_of_order(dev, dma,
-                                                              tmp_order);
-               }
-       }
-       return 0;
-}
diff --git a/drivers/char/drm/drawable.c b/drivers/char/drm/drawable.c
deleted file mode 100644 (file)
index 1328054..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* drawable.c -- IOCTLs for drawables -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-int drm_adddraw(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_draw_t draw;
-
-       draw.handle = 0;        /* NOOP */
-       DRM_DEBUG("%d\n", draw.handle);
-       if (copy_to_user((drm_draw_t *)arg, &draw, sizeof(draw)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_rmdraw(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       return 0;               /* NOOP */
-}
index 101556540df12d7876f66426e39583c3717721a2..ac9f407a7e25843ffb878c4b3e7987c82b9e6aaf 100644 (file)
  * 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
+ * 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.
+ * 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>
@@ -35,8 +35,8 @@
 #ifndef _DRM_H_
 #define _DRM_H_
 
-#include <linux/config.h>
 #if defined(__linux__)
+#include <linux/config.h>
 #include <asm/ioctl.h>         /* For _IO* macros */
 #define DRM_IOCTL_NR(n)             _IOC_NR(n)
 #elif defined(__FreeBSD__)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #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_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID     0
 #define DRM_DEV_GID     0
+#endif
 
-
+#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
+#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                 */
@@ -73,12 +85,20 @@ typedef unsigned int  drm_magic_t;
  * XF86DRIClipRectRec in the server as well */
 
 typedef struct drm_clip_rect {
-           unsigned short x1;
-           unsigned short y1;
-           unsigned short x2;
-           unsigned short y2;
+       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;
+
 /* Seperate include files for the i810/mga/r128 specific structures */
 #include "mga_drm.h"
 #include "i810_drm.h"
@@ -125,10 +145,11 @@ typedef struct drm_control {
 } 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_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 {
@@ -137,9 +158,15 @@ typedef enum drm_map_flags {
        _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_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)         */
@@ -151,6 +178,44 @@ typedef struct drm_map {
                                 /* 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;
+
+typedef enum {
+       _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;
+
+typedef struct drm_stats {
+       unsigned long count;
+       struct {
+               unsigned long   value;
+               drm_stat_type_t 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        */
@@ -193,7 +258,8 @@ typedef struct drm_buf_desc {
        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_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 */
@@ -299,6 +365,11 @@ typedef struct drm_agp_info {
        unsigned short id_device;
 } drm_agp_info_t;
 
+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_IOCTL_BASE                 'd'
 #define DRM_IO(nr)                     _IO(DRM_IOCTL_BASE,nr)
 #define DRM_IOR(nr,size)               _IOR(DRM_IOCTL_BASE,nr,size)
@@ -310,6 +381,9 @@ typedef struct drm_agp_info {
 #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)
@@ -323,6 +397,11 @@ typedef struct drm_agp_info {
 #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)
@@ -346,17 +425,21 @@ typedef struct drm_agp_info {
 #define DRM_IOCTL_AGP_BIND             DRM_IOW( 0x36, drm_agp_binding_t)
 #define DRM_IOCTL_AGP_UNBIND           DRM_IOW( 0x37, drm_agp_binding_t)
 
-/* Mga specific ioctls */
+#define DRM_IOCTL_SG_ALLOC             DRM_IOW( 0x38, drm_scatter_gather_t)
+#define DRM_IOCTL_SG_FREE              DRM_IOW( 0x39, drm_scatter_gather_t)
+
+/* MGA specific ioctls */
 #define DRM_IOCTL_MGA_INIT             DRM_IOW( 0x40, drm_mga_init_t)
-#define DRM_IOCTL_MGA_SWAP             DRM_IOW( 0x41, drm_mga_swap_t)
-#define DRM_IOCTL_MGA_CLEAR            DRM_IOW( 0x42, drm_mga_clear_t)
-#define DRM_IOCTL_MGA_ILOAD            DRM_IOW( 0x43, drm_mga_iload_t)
-#define DRM_IOCTL_MGA_VERTEX           DRM_IOW( 0x44, drm_mga_vertex_t)
-#define DRM_IOCTL_MGA_FLUSH            DRM_IOW( 0x45, drm_lock_t )
+#define DRM_IOCTL_MGA_FLUSH            DRM_IOW( 0x41, drm_lock_t)
+#define DRM_IOCTL_MGA_RESET            DRM_IO(  0x42)
+#define DRM_IOCTL_MGA_SWAP             DRM_IO(  0x43)
+#define DRM_IOCTL_MGA_CLEAR            DRM_IOW( 0x44, drm_mga_clear_t)
+#define DRM_IOCTL_MGA_VERTEX           DRM_IOW( 0x45, drm_mga_vertex_t)
 #define DRM_IOCTL_MGA_INDICES          DRM_IOW( 0x46, drm_mga_indices_t)
-#define DRM_IOCTL_MGA_BLIT             DRM_IOW( 0x47, drm_mga_blit_t)
+#define DRM_IOCTL_MGA_ILOAD            DRM_IOW( 0x47, drm_mga_iload_t)
+#define DRM_IOCTL_MGA_BLIT             DRM_IOW( 0x48, drm_mga_blit_t)
 
-/* I810 specific ioctls */
+/* i810 specific ioctls */
 #define DRM_IOCTL_I810_INIT            DRM_IOW( 0x40, drm_i810_init_t)
 #define DRM_IOCTL_I810_VERTEX          DRM_IOW( 0x41, drm_i810_vertex_t)
 #define DRM_IOCTL_I810_CLEAR           DRM_IOW( 0x42, drm_i810_clear_t)
@@ -381,7 +464,8 @@ typedef struct drm_agp_info {
 #define DRM_IOCTL_R128_BLIT            DRM_IOW( 0x4b, drm_r128_blit_t)
 #define DRM_IOCTL_R128_DEPTH           DRM_IOW( 0x4c, drm_r128_depth_t)
 #define DRM_IOCTL_R128_STIPPLE         DRM_IOW( 0x4d, drm_r128_stipple_t)
-#define DRM_IOCTL_R128_PACKET          DRM_IOWR(0x4e, drm_r128_packet_t)
+#define DRM_IOCTL_R128_INDIRECT                DRM_IOWR(0x4f, drm_r128_indirect_t)
+#define DRM_IOCTL_R128_FULLSCREEN      DRM_IOW( 0x50, drm_r128_fullscreen_t)
 
 /* Radeon specific ioctls */
 #define DRM_IOCTL_RADEON_CP_INIT       DRM_IOW( 0x40, drm_radeon_init_t)
@@ -395,9 +479,9 @@ typedef struct drm_agp_info {
 #define DRM_IOCTL_RADEON_CLEAR         DRM_IOW( 0x48, drm_radeon_clear_t)
 #define DRM_IOCTL_RADEON_VERTEX                DRM_IOW( 0x49, drm_radeon_vertex_t)
 #define DRM_IOCTL_RADEON_INDICES       DRM_IOW( 0x4a, drm_radeon_indices_t)
-#define DRM_IOCTL_RADEON_BLIT          DRM_IOW( 0x4b, drm_radeon_blit_t)
 #define DRM_IOCTL_RADEON_STIPPLE       DRM_IOW( 0x4c, drm_radeon_stipple_t)
 #define DRM_IOCTL_RADEON_INDIRECT      DRM_IOWR(0x4d, drm_radeon_indirect_t)
+#define DRM_IOCTL_RADEON_TEXTURE       DRM_IOWR(0x4e, drm_radeon_texture_t)
 
 #ifdef CONFIG_DRM_SIS
 /* SiS specific ioctls */
index 1c0596df7b19406dc95d207f1a817122dd59cef3..3b282685ece31bab87b2b8a93a62295ca28a8229 100644 (file)
  * 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
+ * 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.
- * 
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
- * 
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #ifndef _DRM_P_H_
@@ -43,7 +43,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
-#include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
@@ -54,7 +53,7 @@
 #include <linux/sched.h>
 #include <linux/smp_lock.h>    /* For (un)lock_kernel */
 #include <linux/mm.h>
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__powerpc__)
 #include <asm/pgtable.h> /* For pte_wrprotect */
 #endif
 #include <asm/io.h>
 #if LINUX_VERSION_CODE < 0x020400
 #include "compat-pre24.h"
 #endif
+#include <asm/pgalloc.h>
 #include "drm.h"
 
+/* DRM template customization defaults
+ */
+#ifndef __HAVE_AGP
+#define __HAVE_AGP             0
+#endif
+#ifndef __HAVE_MTRR
+#define __HAVE_MTRR            0
+#endif
+#ifndef __HAVE_CTX_BITMAP
+#define __HAVE_CTX_BITMAP      0
+#endif
+#ifndef __HAVE_DMA
+#define __HAVE_DMA             0
+#endif
+#ifndef __HAVE_DMA_IRQ
+#define __HAVE_DMA_IRQ         0
+#endif
+#ifndef __HAVE_DMA_WAITLIST
+#define __HAVE_DMA_WAITLIST    0
+#endif
+#ifndef __HAVE_DMA_FREELIST
+#define __HAVE_DMA_FREELIST    0
+#endif
+#ifndef __HAVE_DMA_HISTOGRAM
+#define __HAVE_DMA_HISTOGRAM   0
+#endif
+
+#define __REALLY_HAVE_AGP      (__HAVE_AGP && (defined(CONFIG_AGP) || \
+                                               defined(CONFIG_AGP_MODULE)))
+#define __REALLY_HAVE_MTRR     (__HAVE_MTRR && defined(CONFIG_MTRR))
+
+
+/* Begin the DRM...
+ */
+
 #define DRM_DEBUG_CODE 2         /* Include debugging code (if > 1, then
                                     also include looping detection. */
-#define DRM_DMA_HISTOGRAM 1      /* Make histogram of DMA latency. */
 
 #define DRM_HASH_SIZE        16 /* Size of key hash table                */
 #define DRM_KERNEL_CONTEXT    0         /* Change drm_resctx if changed          */
 #define DRM_MEM_TOTALAGP  16
 #define DRM_MEM_BOUNDAGP  17
 #define DRM_MEM_CTXBITMAP 18
+#define DRM_MEM_STUB      19
+#define DRM_MEM_SGLISTS   20
 
 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 
@@ -164,7 +200,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
        unsigned long prev, cmp;
 
        __asm__ __volatile__(
-       "1:     ldl_l %0,%2\n"
+       "1:     ldl_l %0,%5\n"
        "       cmpeq %0,%3,%1\n"
        "       beq %1,2f\n"
        "       mov %4,%1\n"
@@ -175,7 +211,8 @@ __cmpxchg_u32(volatile int *m, int old, int new)
        "3:     br 1b\n"
        ".previous"
        : "=&r"(prev), "=&r"(cmp), "=m"(*m)
-       : "r"((long) old), "r"(new), "m"(*m));
+       : "r"((long) old), "r"(new), "m"(*m)
+       : "memory" );
 
        return prev;
 }
@@ -186,7 +223,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
        unsigned long prev, cmp;
 
        __asm__ __volatile__(
-       "1:     ldq_l %0,%2\n"
+       "1:     ldq_l %0,%5\n"
        "       cmpeq %0,%3,%1\n"
        "       beq %1,2f\n"
        "       mov %4,%1\n"
@@ -197,7 +234,8 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
        "3:     br 1b\n"
        ".previous"
        : "=&r"(prev), "=&r"(cmp), "=m"(*m)
-       : "r"((long) old), "r"(new), "m"(*m));
+       : "r"((long) old), "r"(new), "m"(*m)
+       : "memory" );
 
        return prev;
 }
@@ -249,27 +287,58 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
        return old;
 }
 
+#elif defined(__powerpc__)
+extern void __cmpxchg_called_with_bad_pointer(void);
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+                                      unsigned long new, int size)
+{
+       unsigned long prev;
+
+       switch (size) {
+       case 4:
+               __asm__ __volatile__(
+                       "sync;"
+                       "0:    lwarx %0,0,%1 ;"
+                       "      cmpl 0,%0,%3;"
+                       "      bne 1f;"
+                       "      stwcx. %2,0,%1;"
+                       "      bne- 0b;"
+                       "1:    "
+                       "sync;"
+                       : "=&r"(prev)
+                       : "r"(ptr), "r"(new), "r"(old)
+                       : "cr0", "memory");
+               return prev;
+       }
+       __cmpxchg_called_with_bad_pointer();
+       return old;
+}
+
+#endif /* i386, powerpc & alpha */
+
+#ifndef __alpha__
 #define cmpxchg(ptr,o,n)                                               \
   ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),             \
                                 (unsigned long)(n),sizeof(*(ptr))))
-#endif /* i386 & alpha */
 #endif
 
+#endif /* !__HAVE_ARCH_CMPXCHG */
+
                                /* Macros to make printk easier */
 #define DRM_ERROR(fmt, arg...) \
        printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
 #define DRM_MEM_ERROR(area, fmt, arg...) \
        printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \
-              drm_mem_stats[area].name , ##arg)
+              DRM(mem_stats)[area].name , ##arg)
 #define DRM_INFO(fmt, arg...)  printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
 
 #if DRM_DEBUG_CODE
-#define DRM_DEBUG(fmt, arg...)                                           \
-       do {                                                              \
-               if (drm_flags&DRM_FLAG_DEBUG)                             \
-                       printk(KERN_DEBUG                                 \
-                              "[" DRM_NAME ":" __FUNCTION__ "] " fmt ,   \
-                              ##arg);                                    \
+#define DRM_DEBUG(fmt, arg...)                                         \
+       do {                                                            \
+               if ( DRM(flags) & DRM_FLAG_DEBUG )                      \
+                       printk(KERN_DEBUG                               \
+                              "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+                              ##arg);                                  \
        } while (0)
 #else
 #define DRM_DEBUG(fmt, arg...)          do { } while (0)
@@ -277,13 +346,36 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 
 #define DRM_PROC_LIMIT (PAGE_SIZE-80)
 
-#define DRM_PROC_PRINT(fmt, arg...)       \
-   len += sprintf(&buf[len], fmt , ##arg); \
-   if (len > DRM_PROC_LIMIT) return len;
+#define DRM_PROC_PRINT(fmt, arg...)                                    \
+   len += sprintf(&buf[len], fmt , ##arg);                             \
+   if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; }
+
+#define DRM_PROC_PRINT_RET(ret, fmt, arg...)                           \
+   len += sprintf(&buf[len], fmt , ##arg);                             \
+   if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
+
+                               /* Mapping helper macros */
+#define DRM_IOREMAP(map)                                               \
+       (map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
 
-#define DRM_PROC_PRINT_RET(ret, fmt, arg...)       \
-   len += sprintf(&buf[len], fmt , ##arg);         \
-   if (len > DRM_PROC_LIMIT) { ret; return len; }
+#define DRM_IOREMAPFREE(map)                                           \
+       do {                                                            \
+               if ( (map)->handle && (map)->size )                     \
+                       DRM(ioremapfree)( (map)->handle, (map)->size ); \
+       } while (0)
+
+#define DRM_FIND_MAP(_map, _o)                                         \
+do {                                                                   \
+       struct list_head *_list;                                        \
+       list_for_each( _list, &dev->maplist->head ) {                   \
+               drm_map_list_t *_entry = (drm_map_list_t *)_list;       \
+               if ( _entry->map &&                                     \
+                    _entry->map->offset == (_o) ) {                    \
+                       (_map) = _entry->map;                           \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+} while(0)
 
                                /* Internal types and structures */
 #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
@@ -294,8 +386,17 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
 #define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
 
-typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
+#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do {      \
+       (_map) = (_dev)->context_sareas[_ctx];          \
+} while(0)
+
+typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg );
+
+typedef struct drm_pci_list {
+       u16 vendor;
+       u16 device;
+} drm_pci_list_t;
 
 typedef struct drm_ioctl_desc {
        drm_ioctl_t          *func;
@@ -305,7 +406,7 @@ typedef struct drm_ioctl_desc {
 
 typedef struct drm_devstate {
        pid_t             owner;        /* X server pid holding x_lock */
-       
+
 } drm_devstate_t;
 
 typedef struct drm_magic_entry {
@@ -366,14 +467,14 @@ typedef struct drm_buf {
 #define DRM_DMA_HISTOGRAM_NEXT(current)         ((current)*10)
 typedef struct drm_histogram {
        atomic_t          total;
-       
+
        atomic_t          queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS];
        atomic_t          dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
        atomic_t          completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
-       
+
        atomic_t          queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
        atomic_t          queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
-       
+
        atomic_t          dma[DRM_DMA_HISTOGRAM_SLOTS];
        atomic_t          schedule[DRM_DMA_HISTOGRAM_SLOTS];
        atomic_t          ctx[DRM_DMA_HISTOGRAM_SLOTS];
@@ -397,7 +498,7 @@ typedef struct drm_freelist {
        int               initialized; /* Freelist in use                  */
        atomic_t          count;       /* Number of free buffers           */
        drm_buf_t         *next;       /* End pointer                      */
-       
+
        wait_queue_head_t waiting;     /* Processes waiting on free bufs   */
        int               low_mark;    /* Low water mark                   */
        int               high_mark;   /* High water mark                  */
@@ -443,9 +544,11 @@ typedef struct drm_queue {
        wait_queue_head_t read_queue;   /* Processes waiting on block_read  */
        atomic_t          block_write;  /* Queue blocked for writes         */
        wait_queue_head_t write_queue;  /* Processes waiting on block_write */
+#if 1
        atomic_t          total_queued; /* Total queued statistic           */
        atomic_t          total_flushed;/* Total flushes statistic          */
        atomic_t          total_locks;  /* Total locks statistics           */
+#endif
        drm_ctx_flags_t   flags;        /* Context preserving and 2D-only   */
        drm_waitlist_t    waitlist;     /* Pending buffers                  */
        wait_queue_head_t flush_queue;  /* Processes waiting until flush    */
@@ -459,11 +562,12 @@ typedef struct drm_lock_data {
 } drm_lock_data_t;
 
 typedef struct drm_device_dma {
+#if 0
                                /* Performance Counters */
        atomic_t          total_prio;   /* Total DRM_DMA_PRIORITY          */
        atomic_t          total_bytes;  /* Total bytes DMA'd               */
        atomic_t          total_dmas;   /* Total DMA buffers dispatched    */
-       
+
        atomic_t          total_missed_dma;  /* Missed drm_do_dma           */
        atomic_t          total_missed_lock; /* Missed lock in drm_do_dma   */
        atomic_t          total_missed_free; /* Missed drm_free_this_buffer */
@@ -472,16 +576,18 @@ typedef struct drm_device_dma {
        atomic_t          total_tried;  /* Tried next_buffer                */
        atomic_t          total_hit;    /* Sent next_buffer                 */
        atomic_t          total_lost;   /* Lost interrupt                   */
+#endif
 
        drm_buf_entry_t   bufs[DRM_MAX_ORDER+1];
        int               buf_count;
        drm_buf_t         **buflist;    /* Vector of pointers info bufs    */
-       int               seg_count; 
+       int               seg_count;
        int               page_count;
        unsigned long     *pagelist;
        unsigned long     byte_count;
        enum {
-          _DRM_DMA_USE_AGP = 0x01
+               _DRM_DMA_USE_AGP = 0x01,
+               _DRM_DMA_USE_SG  = 0x02
        } flags;
 
                                /* DMA support */
@@ -491,7 +597,7 @@ typedef struct drm_device_dma {
        wait_queue_head_t waiting;      /* Processes waiting on free bufs  */
 } drm_device_dma_t;
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+#if __REALLY_HAVE_AGP
 typedef struct drm_agp_mem {
        unsigned long      handle;
        agp_memory         *memory;
@@ -513,18 +619,30 @@ typedef struct drm_agp_head {
 } drm_agp_head_t;
 #endif
 
+typedef struct drm_sg_mem {
+       unsigned long   handle;
+       void            *virtual;
+       int             pages;
+       struct page     **pagelist;
+} drm_sg_mem_t;
+
 typedef struct drm_sigdata {
        int           context;
        drm_hw_lock_t *lock;
 } drm_sigdata_t;
 
+typedef struct drm_map_list {
+       struct list_head        head;
+       drm_map_t               *map;
+} drm_map_list_t;
+
 typedef struct drm_device {
        const char        *name;        /* Simple driver name              */
        char              *unique;      /* Unique identifier: e.g., busid  */
        int               unique_len;   /* Length of unique field          */
        dev_t             device;       /* Device number for mknod         */
        char              *devname;     /* For /proc/interrupts            */
-       
+
        int               blocked;      /* Blocked due to VC switch?       */
        struct proc_dir_entry *root;    /* Root for this device's entries  */
 
@@ -539,17 +657,10 @@ typedef struct drm_device {
        int               buf_use;      /* Buffers in use -- cannot alloc  */
        atomic_t          buf_alloc;    /* Buffer allocation in progress   */
 
-                               /* Performance Counters */
-       atomic_t          total_open;
-       atomic_t          total_close;
-       atomic_t          total_ioctl;
-       atomic_t          total_irq;    /* Total interruptions             */
-       atomic_t          total_ctx;    /* Total context switches          */
-       
-       atomic_t          total_locks;
-       atomic_t          total_unlocks;
-       atomic_t          total_contends;
-       atomic_t          total_sleeps;
+                               /* Performance counters */
+       unsigned long     counters;
+       drm_stat_type_t   types[15];
+       atomic_t          counts[15];
 
                                /* Authentication */
        drm_file_t        *file_first;
@@ -557,9 +668,12 @@ typedef struct drm_device {
        drm_magic_head_t  magiclist[DRM_HASH_SIZE];
 
                                /* Memory management */
-       drm_map_t         **maplist;    /* Vector of pointers to regions   */
+       drm_map_list_t    *maplist;     /* Linked list of regions          */
        int               map_count;    /* Number of mappable regions      */
 
+       drm_map_t         **context_sareas;
+       int               max_context;
+
        drm_vma_entry_t   *vmalist;     /* List of vmas (for debugging)    */
        drm_lock_data_t   lock;         /* Information on hardware lock    */
 
@@ -583,10 +697,10 @@ typedef struct drm_device {
        struct tq_struct  tq;
        cycles_t          ctx_start;
        cycles_t          lck_start;
-#if DRM_DMA_HISTOGRAM
+#if __HAVE_DMA_HISTOGRAM
        drm_histogram_t   histo;
 #endif
-       
+
                                /* Callback to X server for context switch
                                   and for heavy-handed reset. */
        char              buf[DRM_BSZ]; /* Output buffer                   */
@@ -596,10 +710,18 @@ typedef struct drm_device {
        struct fasync_struct *buf_async;/* Processes waiting for SIGIO     */
        wait_queue_head_t buf_readers;  /* Processes waiting to read       */
        wait_queue_head_t buf_writers;  /* Processes waiting to ctx switch */
-       
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+
+#if __REALLY_HAVE_AGP
        drm_agp_head_t    *agp;
 #endif
+#ifdef __alpha__
+#if LINUX_VERSION_CODE < 0x020403
+       struct pci_controler *hose;
+#else
+       struct pci_controller *hose;
+#endif
+#endif
+       drm_sg_mem_t      *sg;  /* Scatter gather memory */
        unsigned long     *ctx_bitmap;
        void              *dev_private;
        drm_sigdata_t     sigdata; /* For block_all_signals */
@@ -607,230 +729,297 @@ typedef struct drm_device {
 } drm_device_t;
 
 
-                               /* Internal function definitions */
-
-                               /* Misc. support (init.c) */
-extern int          drm_flags;
-extern void         drm_parse_options(char *s);
-extern int           drm_cpu_valid(void);
+/* ================================================================
+ * Internal function definitions
+ */
 
+                               /* Misc. support (drm_init.h) */
+extern int          DRM(flags);
+extern void         DRM(parse_options)( char *s );
+extern int           DRM(cpu_valid)( void );
 
-                               /* Device support (fops.c) */
-extern int          drm_open_helper(struct inode *inode, struct file *filp,
-                                    drm_device_t *dev);
-extern int          drm_flush(struct file *filp);
-extern int          drm_release(struct inode *inode, struct file *filp);
-extern int          drm_fasync(int fd, struct file *filp, int on);
-extern ssize_t      drm_read(struct file *filp, char *buf, size_t count,
-                             loff_t *off);
-extern int          drm_write_string(drm_device_t *dev, const char *s);
-extern unsigned int  drm_poll(struct file *filp, struct poll_table_struct *wait);
+                               /* Driver support (drm_drv.h) */
+extern int           DRM(version)(struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg);
+extern int           DRM(open)(struct inode *inode, struct file *filp);
+extern int           DRM(release)(struct inode *inode, struct file *filp);
+extern int           DRM(ioctl)(struct inode *inode, struct file *filp,
+                               unsigned int cmd, unsigned long arg);
+extern int           DRM(lock)(struct inode *inode, struct file *filp,
+                              unsigned int cmd, unsigned long arg);
+extern int           DRM(unlock)(struct inode *inode, struct file *filp,
+                                unsigned int cmd, unsigned long arg);
 
-                               /* Mapping support (vm.c) */
+                               /* Device support (drm_fops.h) */
+extern int          DRM(open_helper)(struct inode *inode, struct file *filp,
+                                     drm_device_t *dev);
+extern int          DRM(flush)(struct file *filp);
+extern int          DRM(release_fuck)(struct inode *inode, struct file *filp);
+extern int          DRM(fasync)(int fd, struct file *filp, int on);
+extern ssize_t      DRM(read)(struct file *filp, char *buf, size_t count,
+                              loff_t *off);
+extern int          DRM(write_string)(drm_device_t *dev, const char *s);
+extern unsigned int  DRM(poll)(struct file *filp,
+                              struct poll_table_struct *wait);
+
+                               /* Mapping support (drm_vm.h) */
 #if LINUX_VERSION_CODE < 0x020317
-extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
+extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
+                                   unsigned long address,
+                                   int write_access);
+extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                                       unsigned long address,
+                                       int write_access);
+extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
+                                       unsigned long address,
+                                       int write_access);
+extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+                                      unsigned long address,
+                                      int write_access);
+#else
+                               /* Return type changed in 2.3.23 */
+extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
                                   unsigned long address,
                                   int write_access);
-extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
+extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
                                       unsigned long address,
                                       int write_access);
-extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
-                                           unsigned long address,
-                                           int write_access);
-extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
+extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
                                       unsigned long address,
                                       int write_access);
-#else
-                               /* Return type changed in 2.3.23 */
-extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
-                                 unsigned long address,
-                                 int write_access);
-extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
-                                     unsigned long address,
-                                     int write_access);
-extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
-                                          unsigned long address,
-                                          int write_access);
-extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
                                      unsigned long address,
                                      int write_access);
 #endif
-extern void         drm_vm_open(struct vm_area_struct *vma);
-extern void         drm_vm_close(struct vm_area_struct *vma);
-extern int          drm_mmap_dma(struct file *filp,
-                                 struct vm_area_struct *vma);
-extern int          drm_mmap(struct file *filp, struct vm_area_struct *vma);
-
-
-                               /* Proc support (proc.c) */
-extern int          drm_proc_init(drm_device_t *dev);
-extern int          drm_proc_cleanup(void);
-
-                               /* Memory management support (memory.c) */
-extern void         drm_mem_init(void);
-extern int          drm_mem_info(char *buf, char **start, off_t offset,
-                                 int len, int *eof, void *data);
-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(const char *s, int area);
-extern void         drm_free(void *pt, size_t size, int area);
-extern unsigned long drm_alloc_pages(int order, int area);
-extern void         drm_free_pages(unsigned long address, int order,
-                                   int area);
-extern void         *drm_ioremap(unsigned long offset, unsigned long size);
-extern void         drm_ioremapfree(void *pt, unsigned long size);
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-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);
+extern void         DRM(vm_open)(struct vm_area_struct *vma);
+extern void         DRM(vm_close)(struct vm_area_struct *vma);
+extern void         DRM(vm_shm_close)(struct vm_area_struct *vma);
+extern int          DRM(mmap_dma)(struct file *filp,
+                                  struct vm_area_struct *vma);
+extern int          DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
+
+                               /* Memory management support (drm_memory.h) */
+extern void         DRM(mem_init)(void);
+extern int          DRM(mem_info)(char *buf, char **start, off_t offset,
+                                  int request, int *eof, void *data);
+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)(const char *s, int area);
+extern void         DRM(free)(void *pt, size_t size, int area);
+extern unsigned long DRM(alloc_pages)(int order, int area);
+extern void         DRM(free_pages)(unsigned long address, int order,
+                                    int area);
+extern void         *DRM(ioremap)(unsigned long offset, unsigned long size);
+extern void         DRM(ioremapfree)(void *pt, unsigned long size);
+
+#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);
 #endif
 
-
-                               /* Buffer management support (bufs.c) */
-extern int          drm_order(unsigned long size);
-extern int          drm_addmap(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_addbufs(struct inode *inode, struct file *filp,
-                                unsigned int cmd, unsigned long arg);
-extern int          drm_infobufs(struct inode *inode, struct file *filp,
-                                 unsigned int cmd, unsigned long arg);
-extern int          drm_markbufs(struct inode *inode, struct file *filp,
-                                 unsigned int cmd, unsigned long arg);
-extern int          drm_freebufs(struct inode *inode, struct file *filp,
-                                 unsigned int cmd, unsigned long arg);
-extern int          drm_mapbufs(struct inode *inode, struct file *filp,
+                               /* Misc. IOCTL support (drm_ioctl.h) */
+extern int          DRM(irq_busid)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int          DRM(getunique)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int          DRM(setunique)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int          DRM(getmap)(struct inode *inode, struct file *filp,
                                 unsigned int cmd, unsigned long arg);
+extern int          DRM(getclient)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int          DRM(getstats)(struct inode *inode, struct file *filp,
+                                  unsigned int cmd, unsigned long arg);
 
-
-                               /* Buffer list management support (lists.c) */
-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);
-
-extern int          drm_freelist_create(drm_freelist_t *bl, int count);
-extern int          drm_freelist_destroy(drm_freelist_t *bl);
-extern int          drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl,
-                                     drm_buf_t *buf);
-extern drm_buf_t     *drm_freelist_get(drm_freelist_t *bl, int block);
-
-                               /* DMA support (gen_dma.c) */
-extern void         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, pid_t pid);
-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);
-extern void         drm_clear_next_buffer(drm_device_t *dev);
-extern int          drm_select_queue(drm_device_t *dev,
-                                     void (*wrapper)(unsigned long));
-extern int          drm_dma_enqueue(drm_device_t *dev, drm_dma_t *dma);
-extern int          drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma);
-#if DRM_DMA_HISTOGRAM
-extern int          drm_histogram_slot(unsigned long count);
-extern void         drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf);
+                               /* Context IOCTL support (drm_context.h) */
+extern int          DRM(resctx)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(addctx)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(modctx)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(getctx)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(switchctx)( struct inode *inode, struct file *filp,
+                                    unsigned int cmd, unsigned long arg );
+extern int          DRM(newctx)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(rmctx)( struct inode *inode, struct file *filp,
+                                unsigned int cmd, unsigned long arg );
+
+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);
+
+#if __HAVE_CTX_BITMAP
+extern int          DRM(ctxbitmap_init)( drm_device_t *dev );
+extern void         DRM(ctxbitmap_cleanup)( drm_device_t *dev );
 #endif
 
+extern int          DRM(setsareactx)( struct inode *inode, struct file *filp,
+                                      unsigned int cmd, unsigned long arg );
+extern int          DRM(getsareactx)( struct inode *inode, struct file *filp,
+                                      unsigned int cmd, unsigned long arg );
 
-                               /* Misc. IOCTL support (ioctl.c) */
-extern int          drm_irq_busid(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-extern int          drm_getunique(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-extern int          drm_setunique(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
+                               /* Drawable IOCTL support (drm_drawable.h) */
+extern int          DRM(adddraw)(struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg);
+extern int          DRM(rmdraw)(struct inode *inode, struct file *filp,
+                                unsigned int cmd, unsigned long arg);
 
 
-                               /* Context IOCTL support (context.c) */
-extern int          drm_resctx(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_addctx(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_modctx(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_getctx(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_switchctx(struct inode *inode, struct file *filp,
+                               /* Authentication IOCTL support (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);
+extern int          DRM(getmagic)(struct inode *inode, struct file *filp,
                                   unsigned int cmd, unsigned long arg);
-extern int          drm_newctx(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_rmctx(struct inode *inode, struct file *filp,
-                              unsigned int cmd, unsigned long arg);
+extern int          DRM(authmagic)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
 
 
-                               /* Drawable IOCTL support (drawable.c) */
-extern int          drm_adddraw(struct inode *inode, struct file *filp,
-                                unsigned int cmd, unsigned long arg);
-extern int          drm_rmdraw(struct inode *inode, struct file *filp,
+                               /* Locking IOCTL support (drm_lock.h) */
+extern int          DRM(block)(struct inode *inode, struct file *filp,
                                unsigned int cmd, unsigned long arg);
-
-
-                               /* Authentication IOCTL support (auth.c) */
-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);
-extern int          drm_getmagic(struct inode *inode, struct file *filp,
+extern int          DRM(unblock)(struct inode *inode, struct file *filp,
                                  unsigned int cmd, unsigned long arg);
-extern int          drm_authmagic(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-
-
-                               /* Locking IOCTL support (lock.c) */
-extern int          drm_block(struct inode *inode, struct file *filp,
-                              unsigned int cmd, unsigned long arg);
-extern int          drm_unblock(struct inode *inode, struct file *filp,
+extern int          DRM(lock_take)(__volatile__ unsigned int *lock,
+                                   unsigned int context);
+extern int          DRM(lock_transfer)(drm_device_t *dev,
+                                       __volatile__ unsigned int *lock,
+                                       unsigned int context);
+extern int          DRM(lock_free)(drm_device_t *dev,
+                                   __volatile__ unsigned int *lock,
+                                   unsigned int context);
+extern int          DRM(finish)(struct inode *inode, struct file *filp,
                                 unsigned int cmd, unsigned long arg);
-extern int          drm_lock_take(__volatile__ unsigned int *lock,
-                                  unsigned int context);
-extern int          drm_lock_transfer(drm_device_t *dev,
-                                      __volatile__ unsigned int *lock,
-                                      unsigned int context);
-extern int          drm_lock_free(drm_device_t *dev,
-                                  __volatile__ unsigned int *lock,
-                                  unsigned int context);
-extern int          drm_finish(struct inode *inode, struct file *filp,
-                               unsigned int cmd, unsigned long arg);
-extern int          drm_flush_unblock(drm_device_t *dev, int context,
-                                      drm_lock_flags_t flags);
-extern int          drm_flush_block_and_flush(drm_device_t *dev, int context,
-                                              drm_lock_flags_t flags);
-extern int           drm_notifier(void *priv);
-
-                               /* Context Bitmap support (ctxbitmap.c) */
-extern int          drm_ctxbitmap_init(drm_device_t *dev);
-extern void         drm_ctxbitmap_cleanup(drm_device_t *dev);
-extern int          drm_ctxbitmap_next(drm_device_t *dev);
-extern void         drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
+extern int          DRM(flush_unblock)(drm_device_t *dev, int context,
+                                       drm_lock_flags_t flags);
+extern int          DRM(flush_block_and_flush)(drm_device_t *dev, int context,
+                                               drm_lock_flags_t flags);
+extern int           DRM(notifier)(void *priv);
+
+                               /* Buffer management support (drm_bufs.h) */
+extern int          DRM(order)( unsigned long size );
+extern int          DRM(addmap)( struct inode *inode, struct file *filp,
+                                 unsigned int cmd, unsigned long arg );
+extern int          DRM(rmmap)( struct inode *inode, struct file *filp,
+                                unsigned int cmd, unsigned long arg );
+#if __HAVE_DMA
+extern int          DRM(addbufs)( struct inode *inode, struct file *filp,
+                                  unsigned int cmd, unsigned long arg );
+extern int          DRM(infobufs)( struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg );
+extern int          DRM(markbufs)( struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg );
+extern int          DRM(freebufs)( struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg );
+extern int          DRM(mapbufs)( struct inode *inode, struct file *filp,
+                                  unsigned int cmd, unsigned long arg );
+
+                               /* 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, pid_t pid);
+#if __HAVE_OLD_DMA
+/* GH: This is a dirty hack for now...
+ */
+extern void         DRM(clear_next_buffer)(drm_device_t *dev);
+extern int          DRM(select_queue)(drm_device_t *dev,
+                                      void (*wrapper)(unsigned long));
+extern int          DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *dma);
+extern int          DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
+#endif
+#if __HAVE_DMA_IRQ
+extern int           DRM(control)( struct inode *inode, struct file *filp,
+                                  unsigned int cmd, unsigned long arg );
+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)( int irq, void *device,
+                                      struct pt_regs *regs );
+#if __HAVE_DMA_IRQ_BH
+extern void          DRM(dma_immediate_bh)( void *dev );
+#endif
+#endif
+#if DRM_DMA_HISTOGRAM
+extern int          DRM(histogram_slot)(unsigned long count);
+extern void         DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf);
+#endif
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-                               /* AGP/GART support (agpsupport.c) */
-extern drm_agp_head_t *drm_agp_init(void);
-extern void           drm_agp_uninit(void);
-extern int            drm_agp_acquire(struct inode *inode, struct file *filp,
-                                     unsigned int cmd, unsigned long arg);
-extern void           _drm_agp_release(void);
-extern int            drm_agp_release(struct inode *inode, struct file *filp,
+                               /* 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
+#if __HAVE_DMA_FREELIST
+extern int          DRM(freelist_create)(drm_freelist_t *bl, int count);
+extern int          DRM(freelist_destroy)(drm_freelist_t *bl);
+extern int          DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl,
+                                      drm_buf_t *buf);
+extern drm_buf_t     *DRM(freelist_get)(drm_freelist_t *bl, int block);
+#endif
+#endif /* __HAVE_DMA */
+
+#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 int            DRM(agp_acquire)(struct inode *inode, struct file *filp,
+                                      unsigned int cmd, unsigned long arg);
+extern void           DRM(agp_do_release)(void);
+extern int            DRM(agp_release)(struct inode *inode, struct file *filp,
+                                      unsigned int cmd, unsigned long arg);
+extern int            DRM(agp_enable)(struct inode *inode, struct file *filp,
                                      unsigned int cmd, unsigned long arg);
-extern int            drm_agp_enable(struct inode *inode, struct file *filp,
-                                    unsigned int cmd, unsigned long arg);
-extern int            drm_agp_info(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-extern int            drm_agp_alloc(struct inode *inode, struct file *filp,
+extern int            DRM(agp_info)(struct inode *inode, struct file *filp,
                                    unsigned int cmd, unsigned long arg);
-extern int            drm_agp_free(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-extern int            drm_agp_unbind(struct inode *inode, struct file *filp,
+extern int            DRM(agp_alloc)(struct inode *inode, struct file *filp,
                                     unsigned int cmd, unsigned long arg);
-extern int            drm_agp_bind(struct inode *inode, struct file *filp,
-                                  unsigned int cmd, unsigned long arg);
-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);
+extern int            DRM(agp_free)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int            DRM(agp_unbind)(struct inode *inode, struct file *filp,
+                                     unsigned int cmd, unsigned long arg);
+extern int            DRM(agp_bind)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+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
+
+                               /* Stub support (drm_stub.h) */
+int                   DRM(stub_register)(const char *name,
+                                        struct file_operations *fops,
+                                        drm_device_t *dev);
+int                   DRM(stub_unregister)(int minor);
+
+                               /* Proc support (drm_proc.h) */
+extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
+                                            int minor,
+                                            struct proc_dir_entry *root,
+                                            struct proc_dir_entry **dev_root);
+extern int            DRM(proc_cleanup)(int minor,
+                                       struct proc_dir_entry *root,
+                                       struct proc_dir_entry *dev_root);
+
+#if __HAVE_SG
+                               /* Scatter Gather Support (drm_scatter.h) */
+extern void           DRM(sg_cleanup)(drm_sg_mem_t *entry);
+extern int            DRM(sg_alloc)(struct inode *inode, struct file *filp,
+                                   unsigned int cmd, unsigned long arg);
+extern int            DRM(sg_free)(struct inode *inode, struct file *filp,
+                                  unsigned int cmd, unsigned long arg);
 #endif
+
+                               /* ATI PCIGART support (ati_pcigart.h) */
+extern unsigned long  DRM(ati_pcigart_init)(drm_device_t *dev);
+extern int            DRM(ati_pcigart_cleanup)(unsigned long address);
+
+#endif /* __KERNEL__ */
 #endif
diff --git a/drivers/char/drm/drm_agpsupport.h b/drivers/char/drm/drm_agpsupport.h
new file mode 100644 (file)
index 0000000..66d1def
--- /dev/null
@@ -0,0 +1,360 @@
+/* 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>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <linux/module.h>
+
+#if __REALLY_HAVE_AGP
+
+#if LINUX_VERSION_CODE < 0x020400
+#include "agpsupport-pre24.h"
+#else
+#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
+#define DRM_AGP_PUT inter_module_put("drm_agp")
+#endif
+
+static const drm_agp_t *drm_agp = NULL;
+
+int DRM(agp_info)(struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       agp_kern_info    *kern;
+       drm_agp_info_t   info;
+
+       if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
+               return -EINVAL;
+
+       kern                   = &dev->agp->agp_info;
+       info.agp_version_major = kern->version.major;
+       info.agp_version_minor = kern->version.minor;
+       info.mode              = kern->mode;
+       info.aperture_base     = kern->aper_base;
+       info.aperture_size     = kern->aper_size * 1024 * 1024;
+       info.memory_allowed    = kern->max_memory << PAGE_SHIFT;
+       info.memory_used       = kern->current_memory << PAGE_SHIFT;
+       info.id_vendor         = kern->device->vendor;
+       info.id_device         = kern->device->device;
+
+       if (copy_to_user((drm_agp_info_t *)arg, &info, sizeof(info)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(agp_acquire)(struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       int              retcode;
+
+       if (!dev->agp || dev->agp->acquired || !drm_agp->acquire)
+               return -EINVAL;
+       if ((retcode = drm_agp->acquire())) return retcode;
+       dev->agp->acquired = 1;
+       return 0;
+}
+
+int DRM(agp_release)(struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+
+       if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
+               return -EINVAL;
+       drm_agp->release();
+       dev->agp->acquired = 0;
+       return 0;
+
+}
+
+void DRM(agp_do_release)(void)
+{
+       if (drm_agp->release) drm_agp->release();
+}
+
+int DRM(agp_enable)(struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_agp_mode_t   mode;
+
+       if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
+               return -EINVAL;
+
+       if (copy_from_user(&mode, (drm_agp_mode_t *)arg, sizeof(mode)))
+               return -EFAULT;
+
+       dev->agp->mode    = mode.mode;
+       drm_agp->enable(mode.mode);
+       dev->agp->base    = dev->agp->agp_info.aper_base;
+       dev->agp->enabled = 1;
+       return 0;
+}
+
+int DRM(agp_alloc)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_agp_buffer_t request;
+       drm_agp_mem_t    *entry;
+       agp_memory       *memory;
+       unsigned long    pages;
+       u32              type;
+
+       if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
+               return -EFAULT;
+       if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
+               return -ENOMEM;
+
+       memset(entry, 0, sizeof(*entry));
+
+       pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+       type = (u32) request.type;
+
+       if (!(memory = DRM(alloc_agp)(pages, type))) {
+               DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+               return -ENOMEM;
+       }
+
+       entry->handle    = (unsigned long)memory->memory;
+       entry->memory    = memory;
+       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;
+
+       request.handle   = entry->handle;
+        request.physical = memory->physical;
+
+       if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) {
+               dev->agp->memory       = entry->next;
+               dev->agp->memory->prev = NULL;
+               DRM(free_agp)(memory, pages);
+               DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+               return -EFAULT;
+       }
+       return 0;
+}
+
+static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
+                                           unsigned long 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)(struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg)
+{
+       drm_file_t        *priv  = filp->private_data;
+       drm_device_t      *dev   = priv->dev;
+       drm_agp_binding_t request;
+       drm_agp_mem_t     *entry;
+
+       if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
+               return -EFAULT;
+       if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+               return -EINVAL;
+       if (!entry->bound) return -EINVAL;
+       return DRM(unbind_agp)(entry->memory);
+}
+
+int DRM(agp_bind)(struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg)
+{
+       drm_file_t        *priv  = filp->private_data;
+       drm_device_t      *dev   = priv->dev;
+       drm_agp_binding_t request;
+       drm_agp_mem_t     *entry;
+       int               retcode;
+       int               page;
+
+       if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
+               return -EINVAL;
+       if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request)))
+               return -EFAULT;
+       if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+               return -EINVAL;
+       if (entry->bound) return -EINVAL;
+       page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
+       if ((retcode = DRM(bind_agp)(entry->memory, page))) return retcode;
+       entry->bound = dev->agp->base + (page << PAGE_SHIFT);
+       DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
+                 dev->agp->base, entry->bound);
+       return 0;
+}
+
+int DRM(agp_free)(struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_agp_buffer_t request;
+       drm_agp_mem_t    *entry;
+
+       if (!dev->agp || !dev->agp->acquired) return -EINVAL;
+       if (copy_from_user(&request, (drm_agp_buffer_t *)arg, sizeof(request)))
+               return -EFAULT;
+       if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
+               return -EINVAL;
+       if (entry->bound) DRM(unbind_agp)(entry->memory);
+
+       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->memory, entry->pages);
+       DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
+       return 0;
+}
+
+drm_agp_head_t *DRM(agp_init)(void)
+{
+       drm_agp_head_t *head         = NULL;
+
+       drm_agp = DRM_AGP_GET;
+       if (drm_agp) {
+               if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
+                       return NULL;
+               memset((void *)head, 0, sizeof(*head));
+               drm_agp->copy_info(&head->agp_info);
+               if (head->agp_info.chipset == NOT_SUPPORTED) {
+                       DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
+                       return NULL;
+               }
+               head->memory = NULL;
+               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;
+
+#if LINUX_VERSION_CODE >= 0x020400
+               case INTEL_I815:        head->chipset = "Intel i815";    break;
+               case INTEL_I840:        head->chipset = "Intel i840";    break;
+               case INTEL_I850:        head->chipset = "Intel i850";    break;
+#endif
+
+               case VIA_GENERIC:       head->chipset = "VIA";           break;
+               case VIA_VP3:           head->chipset = "VIA VP3";       break;
+               case VIA_MVP3:          head->chipset = "VIA MVP3";      break;
+#if LINUX_VERSION_CODE >= 0x020400
+               case VIA_MVP4:          head->chipset = "VIA MVP4";      break;
+               case VIA_APOLLO_KX133:  head->chipset = "VIA Apollo KX133";
+                       break;
+               case VIA_APOLLO_KT133:  head->chipset = "VIA Apollo KT133";
+                       break;
+#endif
+
+               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;
+
+#if LINUX_VERSION_CODE >= 0x020402
+               case ALI_M1621:         head->chipset = "ALi M1621";     break;
+               case ALI_M1631:         head->chipset = "ALi M1631";     break;
+               case ALI_M1632:         head->chipset = "ALi M1632";     break;
+               case ALI_M1641:         head->chipset = "ALi M1641";     break;
+               case ALI_M1647:         head->chipset = "ALi M1647";     break;
+               case ALI_M1651:         head->chipset = "ALi M1651";     break;
+#endif
+
+#if LINUX_VERSION_CODE >= 0x020406
+               case SVWRKS_HE:         head->chipset = "Serverworks HE";
+                       break;
+               case SVWRKS_LE:         head->chipset = "Serverworks LE";
+                       break;
+               case SVWRKS_GENERIC:    head->chipset = "Serverworks Generic";
+                       break;
+#endif
+
+               default:                head->chipset = "Unknown";       break;
+               }
+               DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
+                        head->agp_info.version.major,
+                        head->agp_info.version.minor,
+                        head->chipset,
+                        head->agp_info.aper_base,
+                        head->agp_info.aper_size);
+       }
+       return head;
+}
+
+void DRM(agp_uninit)(void)
+{
+       DRM_AGP_PUT;
+       drm_agp = NULL;
+}
+
+agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
+{
+       if (!drm_agp->allocate_memory) return NULL;
+       return drm_agp->allocate_memory(pages, type);
+}
+
+int DRM(agp_free_memory)(agp_memory *handle)
+{
+       if (!handle || !drm_agp->free_memory) return 0;
+       drm_agp->free_memory(handle);
+       return 1;
+}
+
+int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
+{
+       if (!handle || !drm_agp->bind_memory) return -EINVAL;
+       return drm_agp->bind_memory(handle, start);
+}
+
+int DRM(agp_unbind_memory)(agp_memory *handle)
+{
+       if (!handle || !drm_agp->unbind_memory) return -EINVAL;
+       return drm_agp->unbind_memory(handle);
+}
+
+#endif /* __REALLY_HAVE_AGP */
diff --git a/drivers/char/drm/drm_auth.h b/drivers/char/drm/drm_auth.h
new file mode 100644 (file)
index 0000000..2636e61
--- /dev/null
@@ -0,0 +1,162 @@
+/* drm_auth.h -- IOCTLs for authentication -*- linux-c -*-
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static int DRM(hash_magic)(drm_magic_t magic)
+{
+       return magic & (DRM_HASH_SIZE-1);
+}
+
+static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
+{
+       drm_file_t        *retval = NULL;
+       drm_magic_entry_t *pt;
+       int               hash    = DRM(hash_magic)(magic);
+
+       down(&dev->struct_sem);
+       for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+               if (pt->magic == magic) {
+                       retval = pt->priv;
+                       break;
+               }
+       }
+       up(&dev->struct_sem);
+       return retval;
+}
+
+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(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
+       if (!entry) return -ENOMEM;
+       entry->magic = magic;
+       entry->priv  = priv;
+       entry->next  = NULL;
+
+       down(&dev->struct_sem);
+       if (dev->magiclist[hash].tail) {
+               dev->magiclist[hash].tail->next = entry;
+               dev->magiclist[hash].tail       = entry;
+       } else {
+               dev->magiclist[hash].head       = entry;
+               dev->magiclist[hash].tail       = entry;
+       }
+       up(&dev->struct_sem);
+
+       return 0;
+}
+
+int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
+{
+       drm_magic_entry_t *prev = NULL;
+       drm_magic_entry_t *pt;
+       int               hash;
+
+       DRM_DEBUG("%d\n", magic);
+       hash = DRM(hash_magic)(magic);
+
+       down(&dev->struct_sem);
+       for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
+               if (pt->magic == magic) {
+                       if (dev->magiclist[hash].head == pt) {
+                               dev->magiclist[hash].head = pt->next;
+                       }
+                       if (dev->magiclist[hash].tail == pt) {
+                               dev->magiclist[hash].tail = prev;
+                       }
+                       if (prev) {
+                               prev->next = pt->next;
+                       }
+                       up(&dev->struct_sem);
+                       return 0;
+               }
+       }
+       up(&dev->struct_sem);
+
+       DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
+
+       return -EINVAL;
+}
+
+int DRM(getmagic)(struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg)
+{
+       static drm_magic_t sequence = 0;
+       static spinlock_t  lock     = SPIN_LOCK_UNLOCKED;
+       drm_file_t         *priv    = filp->private_data;
+       drm_device_t       *dev     = priv->dev;
+       drm_auth_t         auth;
+
+                               /* Find unique magic */
+       if (priv->magic) {
+               auth.magic = priv->magic;
+       } else {
+               do {
+                       spin_lock(&lock);
+                       if (!sequence) ++sequence; /* reserve 0 */
+                       auth.magic = sequence++;
+                       spin_unlock(&lock);
+               } while (DRM(find_file)(dev, auth.magic));
+               priv->magic = auth.magic;
+               DRM(add_magic)(dev, priv, auth.magic);
+       }
+
+       DRM_DEBUG("%u\n", auth.magic);
+       if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(authmagic)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_file_t         *priv    = filp->private_data;
+       drm_device_t       *dev     = priv->dev;
+       drm_auth_t         auth;
+       drm_file_t         *file;
+
+       if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth)))
+               return -EFAULT;
+       DRM_DEBUG("%u\n", auth.magic);
+       if ((file = DRM(find_file)(dev, auth.magic))) {
+               file->authenticated = 1;
+               DRM(remove_magic)(dev, auth.magic);
+               return 0;
+       }
+       return -EINVAL;
+}
diff --git a/drivers/char/drm/drm_bufs.h b/drivers/char/drm/drm_bufs.h
new file mode 100644 (file)
index 0000000..ec5dd54
--- /dev/null
@@ -0,0 +1,1140 @@
+/* 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>
+ */
+
+#define __NO_VERSION__
+#include <linux/vmalloc.h>
+#include "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)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_map_t *map;
+       drm_map_list_t *list;
+
+       if ( !(filp->f_mode & 3) ) return -EACCES; /* Require read/write */
+
+       map = DRM(alloc)( sizeof(*map), DRM_MEM_MAPS );
+       if ( !map )
+               return -ENOMEM;
+
+       if ( copy_from_user( map, (drm_map_t *)arg, sizeof(*map) ) ) {
+               DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+               return -EFAULT;
+       }
+
+       /* 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 -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 -EINVAL;
+       }
+       map->mtrr   = -1;
+       map->handle = 0;
+
+       switch ( map->type ) {
+       case _DRM_REGISTERS:
+       case _DRM_FRAME_BUFFER:
+#if !defined(__sparc__) && !defined(__alpha__)
+               if ( map->offset + map->size < map->offset ||
+                    map->offset < virt_to_phys(high_memory) ) {
+                       DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+                       return -EINVAL;
+               }
+#endif
+#ifdef __alpha__
+               map->offset += dev->hose->mem_space->start;
+#endif
+#if __REALLY_HAVE_MTRR
+               if ( map->type == _DRM_FRAME_BUFFER ||
+                    (map->flags & _DRM_WRITE_COMBINING) ) {
+                       map->mtrr = mtrr_add( map->offset, map->size,
+                                             MTRR_TYPE_WRCOMB, 1 );
+               }
+#endif
+               map->handle = DRM(ioremap)( map->offset, map->size );
+               break;
+
+       case _DRM_SHM:
+               map->handle = vmalloc_32(map->size);
+               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 -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:
+#ifdef __alpha__
+               map->offset += dev->hose->mem_space->start;
+#endif
+               map->offset = 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 -EINVAL;
+               }
+               map->offset = map->offset + dev->sg->handle;
+               break;
+
+       default:
+               DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+               return -EINVAL;
+       }
+
+       list = DRM(alloc)(sizeof(*list), DRM_MEM_MAPS);
+       if(!list) {
+               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+               return -EINVAL;
+       }
+       memset(list, 0, sizeof(*list));
+       list->map = map;
+
+       down(&dev->struct_sem);
+       list_add(&list->head, &dev->maplist->head);
+       up(&dev->struct_sem);
+
+       if ( copy_to_user( (drm_map_t *)arg, map, sizeof(*map) ) )
+               return -EFAULT;
+       if ( map->type != _DRM_SHM ) {
+               if ( copy_to_user( &((drm_map_t *)arg)->handle,
+                                  &map->offset,
+                                  sizeof(map->offset) ) )
+                       return -EFAULT;
+       }
+       return 0;
+}
+
+
+/* Remove a map private from list and deallocate resources if the mapping
+ * isn't in use.
+ */
+
+int DRM(rmmap)(struct inode *inode, struct file *filp,
+              unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       struct list_head *list;
+       drm_map_list_t *r_list = NULL;
+       drm_vma_entry_t *pt, *prev;
+       drm_map_t *map;
+       drm_map_t request;
+       int found_maps = 0;
+
+       if (copy_from_user(&request, (drm_map_t *)arg,
+                          sizeof(request))) {
+               return -EFAULT;
+       }
+
+       down(&dev->struct_sem);
+       list = &dev->maplist->head;
+       list_for_each(list, &dev->maplist->head) {
+               r_list = (drm_map_list_t *) list;
+
+               if(r_list->map &&
+                  r_list->map->handle == request.handle &&
+                  r_list->map->flags & _DRM_REMOVABLE) break;
+       }
+
+       /* List has wrapped around to the head pointer, or its empty we didn't
+        * find anything.
+        */
+       if(list == (&dev->maplist->head)) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+       map = r_list->map;
+       list_del(list);
+       DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
+
+       for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+#if LINUX_VERSION_CODE >= 0x020300
+               if (pt->vma->vm_private_data == map) found_maps++;
+#else
+               if (pt->vma->vm_pte == map) found_maps++;
+#endif
+       }
+
+       if(!found_maps) {
+               switch (map->type) {
+               case _DRM_REGISTERS:
+               case _DRM_FRAME_BUFFER:
+#if __REALLY_HAVE_MTRR
+                       if (map->mtrr >= 0) {
+                               int retcode;
+                               retcode = mtrr_del(map->mtrr,
+                                                  map->offset,
+                                                  map->size);
+                               DRM_DEBUG("mtrr_del = %d\n", retcode);
+                       }
+#endif
+                       DRM(ioremapfree)(map->handle, map->size);
+                       break;
+               case _DRM_SHM:
+                       vfree(map->handle);
+                       break;
+               case _DRM_AGP:
+               case _DRM_SCATTER_GATHER:
+                       break;
+               }
+               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+       }
+       up(&dev->struct_sem);
+       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_pages)(entry->seglist[i],
+                                       entry->page_order,
+                                       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);
+
+#if __HAVE_DMA_FREELIST
+               DRM(freelist_destroy)(&entry->freelist);
+#endif
+
+               entry->buf_count = 0;
+       }
+}
+
+#if __REALLY_HAVE_AGP
+int DRM(addbufs_agp)( struct inode *inode, struct file *filp,
+                     unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_desc_t request;
+       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;
+
+       if ( !dma ) return -EINVAL;
+
+       if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       count = request.count;
+       order = DRM(order)( request.size );
+       size = 1 << order;
+
+       alignment  = (request.flags & _DRM_PAGE_ALIGN)
+               ? PAGE_ALIGN(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: %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 -EINVAL;
+       if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+       spin_lock( &dev->count_lock );
+       if ( dev->buf_use ) {
+               spin_unlock( &dev->count_lock );
+               return -EBUSY;
+       }
+       atomic_inc( &dev->buf_alloc );
+       spin_unlock( &dev->count_lock );
+
+       down( &dev->struct_sem );
+       entry = &dma->bufs[order];
+       if ( entry->buf_count ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -ENOMEM; /* May only call once for each order */
+       }
+
+       if (count < 0 || count > 4096) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -EINVAL;
+       }
+
+       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
+                                   DRM_MEM_BUFS );
+       if ( !entry->buflist ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -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->waiting = 0;
+               buf->pending = 0;
+               init_waitqueue_head( &buf->dma_wait );
+               buf->pid     = 0;
+
+               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 );
+
+#if __HAVE_DMA_HISTOGRAM
+               buf->time_queued = 0;
+               buf->time_dispatched = 0;
+               buf->time_completed = 0;
+               buf->time_freed = 0;
+#endif
+               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);
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               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 );
+
+#if __HAVE_DMA_FREELIST
+       DRM(freelist_create)( &entry->freelist, entry->buf_count );
+       for ( i = 0 ; i < entry->buf_count ; i++ ) {
+               DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+       }
+#endif
+       up( &dev->struct_sem );
+
+       request.count = entry->buf_count;
+       request.size = size;
+
+       if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
+               return -EFAULT;
+
+       dma->flags = _DRM_DMA_USE_AGP;
+
+       atomic_dec( &dev->buf_alloc );
+       return 0;
+}
+#endif /* __REALLY_HAVE_AGP */
+
+#if __HAVE_PCI_DMA
+int DRM(addbufs_pci)( struct inode *inode, struct file *filp,
+                     unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_desc_t request;
+       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;
+
+       if ( !dma ) return -EINVAL;
+
+       if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       count = request.count;
+       order = DRM(order)( request.size );
+       size = 1 << order;
+
+       DRM_DEBUG( "count=%d, size=%d (%d), order=%d, queue_count=%d\n",
+                  request.count, request.size, size,
+                  order, dev->queue_count );
+
+       if ( order < DRM_MIN_ORDER || order > DRM_MAX_ORDER ) return -EINVAL;
+       if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+       alignment = (request.flags & _DRM_PAGE_ALIGN)
+               ? PAGE_ALIGN(size) : size;
+       page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+       total = PAGE_SIZE << page_order;
+
+       spin_lock( &dev->count_lock );
+       if ( dev->buf_use ) {
+               spin_unlock( &dev->count_lock );
+               return -EBUSY;
+       }
+       atomic_inc( &dev->buf_alloc );
+       spin_unlock( &dev->count_lock );
+
+       down( &dev->struct_sem );
+       entry = &dma->bufs[order];
+       if ( entry->buf_count ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -ENOMEM; /* May only call once for each order */
+       }
+
+       if (count < 0 || count > 4096) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -EINVAL;
+       }
+
+       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
+                                   DRM_MEM_BUFS );
+       if ( !entry->buflist ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -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 );
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -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 );
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -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 = DRM(alloc_pages)( page_order, 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->waiting = 0;
+                       buf->pending = 0;
+                       init_waitqueue_head( &buf->dma_wait );
+                       buf->pid     = 0;
+#if __HAVE_DMA_HISTOGRAM
+                       buf->time_queued     = 0;
+                       buf->time_dispatched = 0;
+                       buf->time_completed  = 0;
+                       buf->time_freed      = 0;
+#endif
+                       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);
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               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->seg_count += entry->seg_count;
+       dma->page_count += entry->seg_count << page_order;
+       dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+#if __HAVE_DMA_FREELIST
+       DRM(freelist_create)( &entry->freelist, entry->buf_count );
+       for ( i = 0 ; i < entry->buf_count ; i++ ) {
+               DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+       }
+#endif
+       up( &dev->struct_sem );
+
+       request.count = entry->buf_count;
+       request.size = size;
+
+       if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
+               return -EFAULT;
+
+       atomic_dec( &dev->buf_alloc );
+       return 0;
+
+}
+#endif /* __HAVE_PCI_DMA */
+
+#ifdef __HAVE_SG
+int DRM(addbufs_sg)( struct inode *inode, struct file *filp,
+                     unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_desc_t request;
+       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;
+
+       if ( !dma ) return -EINVAL;
+
+       if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
+                             sizeof(request) ) )
+               return -EFAULT;
+
+       count = request.count;
+       order = DRM(order)( request.size );
+       size = 1 << order;
+
+       alignment  = (request.flags & _DRM_PAGE_ALIGN)
+                       ? PAGE_ALIGN(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 -EINVAL;
+       if ( dev->queue_count ) return -EBUSY; /* Not while in use */
+
+       spin_lock( &dev->count_lock );
+       if ( dev->buf_use ) {
+               spin_unlock( &dev->count_lock );
+               return -EBUSY;
+       }
+       atomic_inc( &dev->buf_alloc );
+       spin_unlock( &dev->count_lock );
+
+       down( &dev->struct_sem );
+       entry = &dma->bufs[order];
+       if ( entry->buf_count ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -ENOMEM; /* May only call once for each order */
+       }
+
+       if (count < 0 || count > 4096) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -EINVAL;
+       }
+
+       entry->buflist = DRM(alloc)( count * sizeof(*entry->buflist),
+                                    DRM_MEM_BUFS );
+       if ( !entry->buflist ) {
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               return -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->waiting = 0;
+               buf->pending = 0;
+               init_waitqueue_head( &buf->dma_wait );
+               buf->pid     = 0;
+
+               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);
+                       up( &dev->struct_sem );
+                       atomic_dec( &dev->buf_alloc );
+                       return -ENOMEM;
+               }
+
+               memset( buf->dev_private, 0, buf->dev_priv_size );
+
+# if __HAVE_DMA_HISTOGRAM
+               buf->time_queued = 0;
+               buf->time_dispatched = 0;
+               buf->time_completed = 0;
+               buf->time_freed = 0;
+# endif
+               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);
+               up( &dev->struct_sem );
+               atomic_dec( &dev->buf_alloc );
+               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 );
+
+#if __HAVE_DMA_FREELIST
+       DRM(freelist_create)( &entry->freelist, entry->buf_count );
+       for ( i = 0 ; i < entry->buf_count ; i++ ) {
+               DRM(freelist_put)( dev, &entry->freelist, &entry->buflist[i] );
+       }
+#endif
+       up( &dev->struct_sem );
+
+       request.count = entry->buf_count;
+       request.size = size;
+
+       if ( copy_to_user( (drm_buf_desc_t *)arg, &request, sizeof(request) ) )
+               return -EFAULT;
+
+       dma->flags = _DRM_DMA_USE_SG;
+
+       atomic_dec( &dev->buf_alloc );
+       return 0;
+}
+#endif /* __HAVE_SG */
+
+int DRM(addbufs)( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
+{
+       drm_buf_desc_t request;
+
+       if ( copy_from_user( &request, (drm_buf_desc_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+#if __REALLY_HAVE_AGP
+       if ( request.flags & _DRM_AGP_BUFFER )
+               return DRM(addbufs_agp)( inode, filp, cmd, arg );
+       else
+#endif
+#if __HAVE_SG
+       if ( request.flags & _DRM_SG_BUFFER )
+               return DRM(addbufs_sg)( inode, filp, cmd, arg );
+       else
+#endif
+#if __HAVE_PCI_DMA
+               return DRM(addbufs_pci)( inode, filp, cmd, arg );
+#else
+               return -EINVAL;
+#endif
+}
+
+int DRM(infobufs)( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_info_t request;
+       int i;
+       int count;
+
+       if ( !dma ) return -EINVAL;
+
+       spin_lock( &dev->count_lock );
+       if ( atomic_read( &dev->buf_alloc ) ) {
+               spin_unlock( &dev->count_lock );
+               return -EBUSY;
+       }
+       ++dev->buf_use;         /* Can't allocate more after this call */
+       spin_unlock( &dev->count_lock );
+
+       if ( copy_from_user( &request,
+                            (drm_buf_info_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       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 *to = &request.list[count];
+                               drm_buf_entry_t *from = &dma->bufs[i];
+                               drm_freelist_t *list = &dma->bufs[i].freelist;
+                               if ( copy_to_user( &to->count,
+                                                  &from->buf_count,
+                                                  sizeof(from->buf_count) ) ||
+                                    copy_to_user( &to->size,
+                                                  &from->buf_size,
+                                                  sizeof(from->buf_size) ) ||
+                                    copy_to_user( &to->low_mark,
+                                                  &list->low_mark,
+                                                  sizeof(list->low_mark) ) ||
+                                    copy_to_user( &to->high_mark,
+                                                  &list->high_mark,
+                                                  sizeof(list->high_mark) ) )
+                                       return -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;
+
+       if ( copy_to_user( (drm_buf_info_t *)arg,
+                          &request,
+                          sizeof(request) ) )
+               return -EFAULT;
+
+       return 0;
+}
+
+int DRM(markbufs)( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_desc_t request;
+       int order;
+       drm_buf_entry_t *entry;
+
+       if ( !dma ) return -EINVAL;
+
+       if ( copy_from_user( &request,
+                            (drm_buf_desc_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       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 -EINVAL;
+       entry = &dma->bufs[order];
+
+       if ( request.low_mark < 0 || request.low_mark > entry->buf_count )
+               return -EINVAL;
+       if ( request.high_mark < 0 || request.high_mark > entry->buf_count )
+               return -EINVAL;
+
+       entry->freelist.low_mark  = request.low_mark;
+       entry->freelist.high_mark = request.high_mark;
+
+       return 0;
+}
+
+int DRM(freebufs)( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_free_t request;
+       int i;
+       int idx;
+       drm_buf_t *buf;
+
+       if ( !dma ) return -EINVAL;
+
+       if ( copy_from_user( &request,
+                            (drm_buf_free_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       DRM_DEBUG( "%d\n", request.count );
+       for ( i = 0 ; i < request.count ; i++ ) {
+               if ( copy_from_user( &idx,
+                                    &request.list[i],
+                                    sizeof(idx) ) )
+                       return -EFAULT;
+               if ( idx < 0 || idx >= dma->buf_count ) {
+                       DRM_ERROR( "Index %d (of %d max)\n",
+                                  idx, dma->buf_count - 1 );
+                       return -EINVAL;
+               }
+               buf = dma->buflist[idx];
+               if ( buf->pid != current->pid ) {
+                       DRM_ERROR( "Process %d freeing buffer owned by %d\n",
+                                  current->pid, buf->pid );
+                       return -EINVAL;
+               }
+               DRM(free_buffer)( dev, buf );
+       }
+
+       return 0;
+}
+
+int DRM(mapbufs)( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       int retcode = 0;
+       const int zero = 0;
+       unsigned long virtual;
+       unsigned long address;
+       drm_buf_map_t request;
+       int i;
+
+       if ( !dma ) return -EINVAL;
+
+       spin_lock( &dev->count_lock );
+       if ( atomic_read( &dev->buf_alloc ) ) {
+               spin_unlock( &dev->count_lock );
+               return -EBUSY;
+       }
+       dev->buf_use++;         /* Can't allocate more after this call */
+       spin_unlock( &dev->count_lock );
+
+       if ( copy_from_user( &request, (drm_buf_map_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       if ( request.count >= dma->buf_count ) {
+               if ( (__HAVE_AGP && (dma->flags & _DRM_DMA_USE_AGP)) ||
+                    (__HAVE_SG && (dma->flags & _DRM_DMA_USE_SG)) ) {
+                       drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
+
+                       if ( !map ) {
+                               retcode = -EINVAL;
+                               goto done;
+                       }
+
+#if LINUX_VERSION_CODE <= 0x020402
+                       down( &current->mm->mmap_sem );
+#else
+                       down_write( &current->mm->mmap_sem );
+#endif
+                       virtual = do_mmap( filp, 0, map->size,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED,
+                                          (unsigned long)map->offset );
+#if LINUX_VERSION_CODE <= 0x020402
+                       up( &current->mm->mmap_sem );
+#else
+                       up_write( &current->mm->mmap_sem );
+#endif
+               } else {
+#if LINUX_VERSION_CODE <= 0x020402
+                       down( &current->mm->mmap_sem );
+#else
+                       down_write( &current->mm->mmap_sem );
+#endif
+                       virtual = do_mmap( filp, 0, dma->byte_count,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED, 0 );
+#if LINUX_VERSION_CODE <= 0x020402
+                       up( &current->mm->mmap_sem );
+#else
+                       up_write( &current->mm->mmap_sem );
+#endif
+               }
+               if ( virtual > -1024UL ) {
+                       /* Real error */
+                       retcode = (signed long)virtual;
+                       goto done;
+               }
+               request.virtual = (void *)virtual;
+
+               for ( i = 0 ; i < dma->buf_count ; i++ ) {
+                       if ( copy_to_user( &request.list[i].idx,
+                                          &dma->buflist[i]->idx,
+                                          sizeof(request.list[0].idx) ) ) {
+                               retcode = -EFAULT;
+                               goto done;
+                       }
+                       if ( copy_to_user( &request.list[i].total,
+                                          &dma->buflist[i]->total,
+                                          sizeof(request.list[0].total) ) ) {
+                               retcode = -EFAULT;
+                               goto done;
+                       }
+                       if ( copy_to_user( &request.list[i].used,
+                                          &zero,
+                                          sizeof(zero) ) ) {
+                               retcode = -EFAULT;
+                               goto done;
+                       }
+                       address = virtual + dma->buflist[i]->offset; /* *** */
+                       if ( 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 );
+
+       if ( copy_to_user( (drm_buf_map_t *)arg, &request, sizeof(request) ) )
+               return -EFAULT;
+
+       return retcode;
+}
+
+#endif /* __HAVE_DMA */
diff --git a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h
new file mode 100644 (file)
index 0000000..5e54d81
--- /dev/null
@@ -0,0 +1,772 @@
+/* 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>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if __HAVE_CTX_BITMAP
+
+/* ================================================================
+ * 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 ) {
+               down(&dev->struct_sem);
+               clear_bit( ctx_handle, dev->ctx_bitmap );
+               dev->context_sareas[ctx_handle] = NULL;
+               up(&dev->struct_sem);
+               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;
+
+       down(&dev->struct_sem);
+       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_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);
+                                       up(&dev->struct_sem);
+                                       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);
+                                       up(&dev->struct_sem);
+                                       return -1;
+                               }
+                               dev->context_sareas[bit] = NULL;
+                       }
+               }
+               up(&dev->struct_sem);
+               return bit;
+       }
+       up(&dev->struct_sem);
+       return -1;
+}
+
+int DRM(ctxbitmap_init)( drm_device_t *dev )
+{
+       int i;
+       int temp;
+
+       down(&dev->struct_sem);
+       dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
+                                                       DRM_MEM_CTXBITMAP );
+       if ( dev->ctx_bitmap == NULL ) {
+               up(&dev->struct_sem);
+               return -ENOMEM;
+       }
+       memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
+       dev->context_sareas = NULL;
+       dev->max_context = -1;
+       up(&dev->struct_sem);
+
+       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 )
+{
+       down(&dev->struct_sem);
+       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 );
+       up(&dev->struct_sem);
+}
+
+/* ================================================================
+ * Per Context SAREA Support
+ */
+
+int DRM(getsareactx)(struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_priv_map_t request;
+       drm_map_t *map;
+
+       if (copy_from_user(&request,
+                          (drm_ctx_priv_map_t *)arg,
+                          sizeof(request)))
+               return -EFAULT;
+
+       down(&dev->struct_sem);
+       if ((int)request.ctx_id >= dev->max_context) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+
+       map = dev->context_sareas[request.ctx_id];
+       up(&dev->struct_sem);
+
+       request.handle = map->handle;
+       if (copy_to_user((drm_ctx_priv_map_t *)arg, &request, sizeof(request)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(setsareactx)(struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_priv_map_t request;
+       drm_map_t *map = NULL;
+       drm_map_list_t *r_list;
+       struct list_head *list;
+
+       if (copy_from_user(&request,
+                          (drm_ctx_priv_map_t *)arg,
+                          sizeof(request)))
+               return -EFAULT;
+
+       down(&dev->struct_sem);
+       list_for_each(list, &dev->maplist->head) {
+               r_list = (drm_map_list_t *)list;
+               if(r_list->map &&
+                  r_list->map->handle == request.handle) break;
+       }
+       if (list == &(dev->maplist->head)) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+       map = r_list->map;
+       up(&dev->struct_sem);
+
+       if (!map) return -EINVAL;
+
+       down(&dev->struct_sem);
+       if ((int)request.ctx_id >= dev->max_context) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+       dev->context_sareas[request.ctx_id] = map;
+       up(&dev->struct_sem);
+       return 0;
+}
+
+/* ================================================================
+ * The actual DRM context handling routines
+ */
+
+int DRM(context_switch)( drm_device_t *dev, int old, int new )
+{
+        char buf[64];
+
+        if ( test_and_set_bit( 0, &dev->context_flag ) ) {
+                DRM_ERROR( "Reentering -- FIXME\n" );
+                return -EBUSY;
+        }
+
+#if __HAVE_DMA_HISTOGRAM
+        dev->ctx_start = get_cycles();
+#endif
+
+        DRM_DEBUG( "Context switch from %d to %d\n", old, new );
+
+        if ( new == dev->last_context ) {
+                clear_bit( 0, &dev->context_flag );
+                return 0;
+        }
+
+        if ( DRM(flags) & DRM_FLAG_NOCTX ) {
+                DRM(context_switch_complete)( dev, new );
+        } else {
+                sprintf( buf, "C %d %d\n", old, new );
+                DRM(write_string)( dev, buf );
+        }
+
+        return 0;
+}
+
+int DRM(context_switch_complete)( drm_device_t *dev, int new )
+{
+        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
+        dev->last_switch  = jiffies;
+
+        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. */
+#if __HAVE_DMA_HISTOGRAM
+        atomic_inc( &dev->histo.ctx[DRM(histogram_slot)(get_cycles()
+                                                       - dev->ctx_start)] );
+
+#endif
+        clear_bit( 0, &dev->context_flag );
+        wake_up( &dev->context_wait );
+
+        return 0;
+}
+
+int DRM(resctx)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_ctx_res_t res;
+       drm_ctx_t ctx;
+       int i;
+
+       if ( copy_from_user( &res, (drm_ctx_res_t *)arg, sizeof(res) ) )
+               return -EFAULT;
+
+       if ( res.count >= DRM_RESERVED_CONTEXTS ) {
+               memset( &ctx, 0, sizeof(ctx) );
+               for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
+                       ctx.handle = i;
+                       if ( copy_to_user( &res.contexts[i],
+                                          &i, sizeof(i) ) )
+                               return -EFAULT;
+               }
+       }
+       res.count = DRM_RESERVED_CONTEXTS;
+
+       if ( copy_to_user( (drm_ctx_res_t *)arg, &res, sizeof(res) ) )
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(addctx)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_ctx_t ctx;
+
+       if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
+               return -EFAULT;
+
+       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 ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) )
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(modctx)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       /* This does nothing */
+       return 0;
+}
+
+int DRM(getctx)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_ctx_t ctx;
+
+       if ( copy_from_user( &ctx, (drm_ctx_t*)arg, sizeof(ctx) ) )
+               return -EFAULT;
+
+       /* This is 0, because we don't handle any context flags */
+       ctx.flags = 0;
+
+       if ( copy_to_user( (drm_ctx_t*)arg, &ctx, sizeof(ctx) ) )
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(switchctx)( struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_ctx_t ctx;
+
+       if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
+               return -EFAULT;
+
+       DRM_DEBUG( "%d\n", ctx.handle );
+       return DRM(context_switch)( dev, dev->last_context, ctx.handle );
+}
+
+int DRM(newctx)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_ctx_t ctx;
+
+       if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
+               return -EFAULT;
+
+       DRM_DEBUG( "%d\n", ctx.handle );
+       DRM(context_switch_complete)( dev, ctx.handle );
+
+       return 0;
+}
+
+int DRM(rmctx)( struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_ctx_t ctx;
+
+       if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) )
+               return -EFAULT;
+
+       DRM_DEBUG( "%d\n", ctx.handle );
+       if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
+               priv->remove_auth_on_close = 1;
+       }
+       if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
+               DRM(ctxbitmap_free)( dev, ctx.handle );
+       }
+
+       return 0;
+}
+
+
+#else /* __HAVE_CTX_BITMAP */
+
+/* ================================================================
+ * Old-style context support
+ */
+
+
+int DRM(context_switch)(drm_device_t *dev, int old, int new)
+{
+       char        buf[64];
+       drm_queue_t *q;
+
+#if 0
+       atomic_inc(&dev->total_ctx);
+#endif
+
+       if (test_and_set_bit(0, &dev->context_flag)) {
+               DRM_ERROR("Reentering -- FIXME\n");
+               return -EBUSY;
+       }
+
+#if __HAVE_DMA_HISTOGRAM
+       dev->ctx_start = get_cycles();
+#endif
+
+       DRM_DEBUG("Context switch from %d to %d\n", old, new);
+
+       if (new >= dev->queue_count) {
+               clear_bit(0, &dev->context_flag);
+               return -EINVAL;
+       }
+
+       if (new == dev->last_context) {
+               clear_bit(0, &dev->context_flag);
+               return 0;
+       }
+
+       q = dev->queuelist[new];
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) == 1) {
+               atomic_dec(&q->use_count);
+               clear_bit(0, &dev->context_flag);
+               return -EINVAL;
+       }
+
+       if (DRM(flags) & DRM_FLAG_NOCTX) {
+               DRM(context_switch_complete)(dev, new);
+       } else {
+               sprintf(buf, "C %d %d\n", old, new);
+               DRM(write_string)(dev, buf);
+       }
+
+       atomic_dec(&q->use_count);
+
+       return 0;
+}
+
+int DRM(context_switch_complete)(drm_device_t *dev, int new)
+{
+       drm_device_dma_t *dma = dev->dma;
+
+       dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
+       dev->last_switch  = jiffies;
+
+       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+               DRM_ERROR("Lock isn't held after context switch\n");
+       }
+
+       if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
+               if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
+                                 DRM_KERNEL_CONTEXT)) {
+                       DRM_ERROR("Cannot free lock\n");
+               }
+       }
+
+#if __HAVE_DMA_HISTOGRAM
+       atomic_inc(&dev->histo.ctx[DRM(histogram_slot)(get_cycles()
+                                                     - dev->ctx_start)]);
+
+#endif
+       clear_bit(0, &dev->context_flag);
+       wake_up_interruptible(&dev->context_wait);
+
+       return 0;
+}
+
+static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
+{
+       DRM_DEBUG("\n");
+
+       if (atomic_read(&q->use_count) != 1
+           || atomic_read(&q->finalization)
+           || atomic_read(&q->block_count)) {
+               DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
+                         atomic_read(&q->use_count),
+                         atomic_read(&q->finalization),
+                         atomic_read(&q->block_count));
+       }
+
+       atomic_set(&q->finalization,  0);
+       atomic_set(&q->block_count,   0);
+       atomic_set(&q->block_read,    0);
+       atomic_set(&q->block_write,   0);
+       atomic_set(&q->total_queued,  0);
+       atomic_set(&q->total_flushed, 0);
+       atomic_set(&q->total_locks,   0);
+
+       init_waitqueue_head(&q->write_queue);
+       init_waitqueue_head(&q->read_queue);
+       init_waitqueue_head(&q->flush_queue);
+
+       q->flags = ctx->flags;
+
+       DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
+
+       return 0;
+}
+
+
+/* drm_alloc_queue:
+PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
+       disappear (so all deallocation must be done after IOCTLs are off)
+     2) dev->queue_count < dev->queue_slots
+     3) dev->queuelist[i].use_count == 0 and
+       dev->queuelist[i].finalization == 0 if i not in use
+POST: 1) dev->queuelist[i].use_count == 1
+      2) dev->queue_count < dev->queue_slots */
+
+static int DRM(alloc_queue)(drm_device_t *dev)
+{
+       int         i;
+       drm_queue_t *queue;
+       int         oldslots;
+       int         newslots;
+                               /* Check for a free queue */
+       for (i = 0; i < dev->queue_count; i++) {
+               atomic_inc(&dev->queuelist[i]->use_count);
+               if (atomic_read(&dev->queuelist[i]->use_count) == 1
+                   && !atomic_read(&dev->queuelist[i]->finalization)) {
+                       DRM_DEBUG("%d (free)\n", i);
+                       return i;
+               }
+               atomic_dec(&dev->queuelist[i]->use_count);
+       }
+                               /* Allocate a new queue */
+       down(&dev->struct_sem);
+
+       queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+       memset(queue, 0, sizeof(*queue));
+       atomic_set(&queue->use_count, 1);
+
+       ++dev->queue_count;
+       if (dev->queue_count >= dev->queue_slots) {
+               oldslots = dev->queue_slots * sizeof(*dev->queuelist);
+               if (!dev->queue_slots) dev->queue_slots = 1;
+               dev->queue_slots *= 2;
+               newslots = dev->queue_slots * sizeof(*dev->queuelist);
+
+               dev->queuelist = DRM(realloc)(dev->queuelist,
+                                             oldslots,
+                                             newslots,
+                                             DRM_MEM_QUEUES);
+               if (!dev->queuelist) {
+                       up(&dev->struct_sem);
+                       DRM_DEBUG("out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+       dev->queuelist[dev->queue_count-1] = queue;
+
+       up(&dev->struct_sem);
+       DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
+       return dev->queue_count - 1;
+}
+
+int DRM(resctx)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       drm_ctx_res_t   res;
+       drm_ctx_t       ctx;
+       int             i;
+
+       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
+       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
+               return -EFAULT;
+       if (res.count >= DRM_RESERVED_CONTEXTS) {
+               memset(&ctx, 0, sizeof(ctx));
+               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+                       ctx.handle = i;
+                       if (copy_to_user(&res.contexts[i],
+                                        &i,
+                                        sizeof(i)))
+                               return -EFAULT;
+               }
+       }
+       res.count = DRM_RESERVED_CONTEXTS;
+       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(addctx)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+       if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
+                               /* Init kernel's context and get a new one. */
+               DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+               ctx.handle = DRM(alloc_queue)(dev);
+       }
+       DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
+       DRM_DEBUG("%d\n", ctx.handle);
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(modctx)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+       drm_queue_t     *q;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+
+       DRM_DEBUG("%d\n", ctx.handle);
+
+       if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
+       q = dev->queuelist[ctx.handle];
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) == 1) {
+                               /* No longer in use */
+               atomic_dec(&q->use_count);
+               return -EINVAL;
+       }
+
+       if (DRM_BUFCOUNT(&q->waitlist)) {
+               atomic_dec(&q->use_count);
+               return -EBUSY;
+       }
+
+       q->flags = ctx.flags;
+
+       atomic_dec(&q->use_count);
+       return 0;
+}
+
+int DRM(getctx)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+       drm_queue_t     *q;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+
+       DRM_DEBUG("%d\n", ctx.handle);
+
+       if (ctx.handle >= dev->queue_count) return -EINVAL;
+       q = dev->queuelist[ctx.handle];
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) == 1) {
+                               /* No longer in use */
+               atomic_dec(&q->use_count);
+               return -EINVAL;
+       }
+
+       ctx.flags = q->flags;
+       atomic_dec(&q->use_count);
+
+       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
+               return -EFAULT;
+
+       return 0;
+}
+
+int DRM(switchctx)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+       DRM_DEBUG("%d\n", ctx.handle);
+       return DRM(context_switch)(dev, dev->last_context, ctx.handle);
+}
+
+int DRM(newctx)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+       DRM_DEBUG("%d\n", ctx.handle);
+       DRM(context_switch_complete)(dev, ctx.handle);
+
+       return 0;
+}
+
+int DRM(rmctx)(struct inode *inode, struct file *filp,
+              unsigned int cmd, unsigned long arg)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_ctx_t       ctx;
+       drm_queue_t     *q;
+       drm_buf_t       *buf;
+
+       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
+               return -EFAULT;
+       DRM_DEBUG("%d\n", ctx.handle);
+
+       if (ctx.handle >= dev->queue_count) return -EINVAL;
+       q = dev->queuelist[ctx.handle];
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) == 1) {
+                               /* No longer in use */
+               atomic_dec(&q->use_count);
+               return -EINVAL;
+       }
+
+       atomic_inc(&q->finalization); /* Mark queue in finalization state */
+       atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
+                                        finalization) */
+
+       while (test_and_set_bit(0, &dev->interrupt_flag)) {
+               schedule();
+               if (signal_pending(current)) {
+                       clear_bit(0, &dev->interrupt_flag);
+                       return -EINTR;
+               }
+       }
+                               /* Remove queued buffers */
+       while ((buf = DRM(waitlist_get)(&q->waitlist))) {
+               DRM(free_buffer)(dev, buf);
+       }
+       clear_bit(0, &dev->interrupt_flag);
+
+                               /* Wakeup blocked processes */
+       wake_up_interruptible(&q->read_queue);
+       wake_up_interruptible(&q->write_queue);
+       wake_up_interruptible(&q->flush_queue);
+
+                               /* Finalization over.  Queue is made
+                                  available when both use_count and
+                                  finalization become 0, which won't
+                                  happen until all the waiting processes
+                                  stop waiting. */
+       atomic_dec(&q->finalization);
+       return 0;
+}
+
+#endif /* __HAVE_CTX_BITMAP */
diff --git a/drivers/char/drm/drm_dma.h b/drivers/char/drm/drm_dma.h
new file mode 100644 (file)
index 0000000..85fa147
--- /dev/null
@@ -0,0 +1,603 @@
+/* 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>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#include <linux/interrupt.h>   /* For task queue support */
+
+#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_SHARED_IRQ
+#define DRM_IRQ_TYPE           SA_SHIRQ
+#else
+#define DRM_IRQ_TYPE           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 -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_pages)(dma->bufs[i].seglist[j],
+                                               dma->bufs[i].page_order,
+                                               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 __HAVE_DMA_FREELIST
+                       DRM(freelist_destroy)(&dma->bufs[i].freelist);
+#endif
+               }
+       }
+
+       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;
+}
+
+
+#if __HAVE_DMA_HISTOGRAM
+/* This is slow, but is useful for debugging. */
+int DRM(histogram_slot)(unsigned long count)
+{
+       int value = DRM_DMA_HISTOGRAM_INITIAL;
+       int slot;
+
+       for (slot = 0;
+            slot < DRM_DMA_HISTOGRAM_SLOTS;
+            ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) {
+               if (count < value) return slot;
+       }
+       return DRM_DMA_HISTOGRAM_SLOTS - 1;
+}
+
+void DRM(histogram_compute)(drm_device_t *dev, drm_buf_t *buf)
+{
+       cycles_t queued_to_dispatched;
+       cycles_t dispatched_to_completed;
+       cycles_t completed_to_freed;
+       int      q2d, d2c, c2f, q2c, q2f;
+
+       if (buf->time_queued) {
+               queued_to_dispatched    = (buf->time_dispatched
+                                          - buf->time_queued);
+               dispatched_to_completed = (buf->time_completed
+                                          - buf->time_dispatched);
+               completed_to_freed      = (buf->time_freed
+                                          - buf->time_completed);
+
+               q2d = DRM(histogram_slot)(queued_to_dispatched);
+               d2c = DRM(histogram_slot)(dispatched_to_completed);
+               c2f = DRM(histogram_slot)(completed_to_freed);
+
+               q2c = DRM(histogram_slot)(queued_to_dispatched
+                                         + dispatched_to_completed);
+               q2f = DRM(histogram_slot)(queued_to_dispatched
+                                         + dispatched_to_completed
+                                         + completed_to_freed);
+
+               atomic_inc(&dev->histo.total);
+               atomic_inc(&dev->histo.queued_to_dispatched[q2d]);
+               atomic_inc(&dev->histo.dispatched_to_completed[d2c]);
+               atomic_inc(&dev->histo.completed_to_freed[c2f]);
+
+               atomic_inc(&dev->histo.queued_to_completed[q2c]);
+               atomic_inc(&dev->histo.queued_to_freed[q2f]);
+
+       }
+       buf->time_queued     = 0;
+       buf->time_dispatched = 0;
+       buf->time_completed  = 0;
+       buf->time_freed      = 0;
+}
+#endif
+
+void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
+{
+       if (!buf) return;
+
+       buf->waiting  = 0;
+       buf->pending  = 0;
+       buf->pid      = 0;
+       buf->used     = 0;
+#if __HAVE_DMA_HISTOGRAM
+       buf->time_completed = get_cycles();
+#endif
+
+       if ( __HAVE_DMA_WAITQUEUE && waitqueue_active(&buf->dma_wait)) {
+               wake_up_interruptible(&buf->dma_wait);
+       }
+#if __HAVE_DMA_FREELIST
+       else {
+               drm_device_dma_t *dma = dev->dma;
+                               /* If processes are waiting, the last one
+                                  to wake will put the buffer on the free
+                                  list.  If no processes are waiting, we
+                                  put the buffer on the freelist here. */
+               DRM(freelist_put)(dev, &dma->bufs[buf->order].freelist, buf);
+       }
+#endif
+}
+
+#if !__HAVE_DMA_RECLAIM
+void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
+{
+       drm_device_dma_t *dma = dev->dma;
+       int              i;
+
+       if (!dma) return;
+       for (i = 0; i < dma->buf_count; i++) {
+               if (dma->buflist[i]->pid == pid) {
+                       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
+
+
+/* GH: This is a big hack for now...
+ */
+#if __HAVE_OLD_DMA
+
+void DRM(clear_next_buffer)(drm_device_t *dev)
+{
+       drm_device_dma_t *dma = dev->dma;
+
+       dma->next_buffer = NULL;
+       if (dma->next_queue && !DRM_BUFCOUNT(&dma->next_queue->waitlist)) {
+               wake_up_interruptible(&dma->next_queue->flush_queue);
+       }
+       dma->next_queue  = NULL;
+}
+
+int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long))
+{
+       int        i;
+       int        candidate = -1;
+       int        j         = jiffies;
+
+       if (!dev) {
+               DRM_ERROR("No device\n");
+               return -1;
+       }
+       if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) {
+                               /* This only happens between the time the
+                                  interrupt is initialized and the time
+                                  the queues are initialized. */
+               return -1;
+       }
+
+                               /* Doing "while locked" DMA? */
+       if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
+               return DRM_KERNEL_CONTEXT;
+       }
+
+                               /* If there are buffers on the last_context
+                                  queue, and we have not been executing
+                                  this context very long, continue to
+                                  execute this context. */
+       if (dev->last_switch <= j
+           && dev->last_switch + DRM_TIME_SLICE > j
+           && DRM_WAITCOUNT(dev, dev->last_context)) {
+               return dev->last_context;
+       }
+
+                               /* Otherwise, find a candidate */
+       for (i = dev->last_checked + 1; i < dev->queue_count; i++) {
+               if (DRM_WAITCOUNT(dev, i)) {
+                       candidate = dev->last_checked = i;
+                       break;
+               }
+       }
+
+       if (candidate < 0) {
+               for (i = 0; i < dev->queue_count; i++) {
+                       if (DRM_WAITCOUNT(dev, i)) {
+                               candidate = dev->last_checked = i;
+                               break;
+                       }
+               }
+       }
+
+       if (wrapper
+           && candidate >= 0
+           && candidate != dev->last_context
+           && dev->last_switch <= j
+           && dev->last_switch + DRM_TIME_SLICE > j) {
+               if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) {
+                       del_timer(&dev->timer);
+                       dev->timer.function = wrapper;
+                       dev->timer.data     = (unsigned long)dev;
+                       dev->timer.expires  = dev->last_switch+DRM_TIME_SLICE;
+                       add_timer(&dev->timer);
+               }
+               return -1;
+       }
+
+       return candidate;
+}
+
+
+int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d)
+{
+       int               i;
+       drm_queue_t       *q;
+       drm_buf_t         *buf;
+       int               idx;
+       int               while_locked = 0;
+       drm_device_dma_t  *dma = dev->dma;
+       DECLARE_WAITQUEUE(entry, current);
+
+       DRM_DEBUG("%d\n", d->send_count);
+
+       if (d->flags & _DRM_DMA_WHILE_LOCKED) {
+               int context = dev->lock.hw_lock->lock;
+
+               if (!_DRM_LOCK_IS_HELD(context)) {
+                       DRM_ERROR("No lock held during \"while locked\""
+                                 " request\n");
+                       return -EINVAL;
+               }
+               if (d->context != _DRM_LOCKING_CONTEXT(context)
+                   && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) {
+                       DRM_ERROR("Lock held by %d while %d makes"
+                                 " \"while locked\" request\n",
+                                 _DRM_LOCKING_CONTEXT(context),
+                                 d->context);
+                       return -EINVAL;
+               }
+               q = dev->queuelist[DRM_KERNEL_CONTEXT];
+               while_locked = 1;
+       } else {
+               q = dev->queuelist[d->context];
+       }
+
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->block_write)) {
+               add_wait_queue(&q->write_queue, &entry);
+               atomic_inc(&q->block_count);
+               for (;;) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       if (!atomic_read(&q->block_write)) break;
+                       schedule();
+                       if (signal_pending(current)) {
+                               atomic_dec(&q->use_count);
+                               remove_wait_queue(&q->write_queue, &entry);
+                               return -EINTR;
+                       }
+               }
+               atomic_dec(&q->block_count);
+               current->state = TASK_RUNNING;
+               remove_wait_queue(&q->write_queue, &entry);
+       }
+
+       for (i = 0; i < d->send_count; i++) {
+               idx = d->send_indices[i];
+               if (idx < 0 || idx >= dma->buf_count) {
+                       atomic_dec(&q->use_count);
+                       DRM_ERROR("Index %d (of %d max)\n",
+                                 d->send_indices[i], dma->buf_count - 1);
+                       return -EINVAL;
+               }
+               buf = dma->buflist[ idx ];
+               if (buf->pid != current->pid) {
+                       atomic_dec(&q->use_count);
+                       DRM_ERROR("Process %d using buffer owned by %d\n",
+                                 current->pid, buf->pid);
+                       return -EINVAL;
+               }
+               if (buf->list != DRM_LIST_NONE) {
+                       atomic_dec(&q->use_count);
+                       DRM_ERROR("Process %d using buffer %d on list %d\n",
+                                 current->pid, buf->idx, buf->list);
+               }
+               buf->used         = d->send_sizes[i];
+               buf->while_locked = while_locked;
+               buf->context      = d->context;
+               if (!buf->used) {
+                       DRM_ERROR("Queueing 0 length buffer\n");
+               }
+               if (buf->pending) {
+                       atomic_dec(&q->use_count);
+                       DRM_ERROR("Queueing pending buffer:"
+                                 " buffer %d, offset %d\n",
+                                 d->send_indices[i], i);
+                       return -EINVAL;
+               }
+               if (buf->waiting) {
+                       atomic_dec(&q->use_count);
+                       DRM_ERROR("Queueing waiting buffer:"
+                                 " buffer %d, offset %d\n",
+                                 d->send_indices[i], i);
+                       return -EINVAL;
+               }
+               buf->waiting = 1;
+               if (atomic_read(&q->use_count) == 1
+                   || atomic_read(&q->finalization)) {
+                       DRM(free_buffer)(dev, buf);
+               } else {
+                       DRM(waitlist_put)(&q->waitlist, buf);
+                       atomic_inc(&q->total_queued);
+               }
+       }
+       atomic_dec(&q->use_count);
+
+       return 0;
+}
+
+static int DRM(dma_get_buffers_of_order)(drm_device_t *dev, drm_dma_t *d,
+                                        int order)
+{
+       int               i;
+       drm_buf_t         *buf;
+       drm_device_dma_t  *dma = dev->dma;
+
+       for (i = d->granted_count; i < d->request_count; i++) {
+               buf = DRM(freelist_get)(&dma->bufs[order].freelist,
+                                       d->flags & _DRM_DMA_WAIT);
+               if (!buf) break;
+               if (buf->pending || buf->waiting) {
+                       DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n",
+                                 buf->idx,
+                                 buf->pid,
+                                 buf->waiting,
+                                 buf->pending);
+               }
+               buf->pid     = current->pid;
+               if (copy_to_user(&d->request_indices[i],
+                                &buf->idx,
+                                sizeof(buf->idx)))
+                       return -EFAULT;
+
+               if (copy_to_user(&d->request_sizes[i],
+                                &buf->total,
+                                sizeof(buf->total)))
+                       return -EFAULT;
+
+               ++d->granted_count;
+       }
+       return 0;
+}
+
+
+int DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma)
+{
+       int               order;
+       int               retcode = 0;
+       int               tmp_order;
+
+       order = DRM(order)(dma->request_size);
+
+       dma->granted_count = 0;
+       retcode            = DRM(dma_get_buffers_of_order)(dev, dma, order);
+
+       if (dma->granted_count < dma->request_count
+           && (dma->flags & _DRM_DMA_SMALLER_OK)) {
+               for (tmp_order = order - 1;
+                    !retcode
+                            && dma->granted_count < dma->request_count
+                            && tmp_order >= DRM_MIN_ORDER;
+                    --tmp_order) {
+
+                       retcode = DRM(dma_get_buffers_of_order)(dev, dma,
+                                                               tmp_order);
+               }
+       }
+
+       if (dma->granted_count < dma->request_count
+           && (dma->flags & _DRM_DMA_LARGER_OK)) {
+               for (tmp_order = order + 1;
+                    !retcode
+                            && dma->granted_count < dma->request_count
+                            && tmp_order <= DRM_MAX_ORDER;
+                    ++tmp_order) {
+
+                       retcode = DRM(dma_get_buffers_of_order)(dev, dma,
+                                                               tmp_order);
+               }
+       }
+       return 0;
+}
+
+#endif /* __HAVE_OLD_DMA */
+
+
+#if __HAVE_DMA_IRQ
+
+int DRM(irq_install)( drm_device_t *dev, int irq )
+{
+       int ret;
+
+       if ( !irq )
+               return -EINVAL;
+
+       down( &dev->struct_sem );
+       if ( dev->irq ) {
+               up( &dev->struct_sem );
+               return -EBUSY;
+       }
+       dev->irq = irq;
+       up( &dev->struct_sem );
+
+       DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+       dev->context_flag = 0;
+       dev->interrupt_flag = 0;
+       dev->dma_flag = 0;
+
+       dev->dma->next_buffer = NULL;
+       dev->dma->next_queue = NULL;
+       dev->dma->this_buffer = NULL;
+
+#if __HAVE_DMA_IRQ_BH
+       INIT_LIST_HEAD( &dev->tq.list );
+       dev->tq.sync = 0;
+       dev->tq.routine = DRM(dma_immediate_bh);
+       dev->tq.data = dev;
+#endif
+
+                               /* Before installing handler */
+       DRIVER_PREINSTALL();
+
+                               /* Install handler */
+       ret = request_irq( dev->irq, DRM(dma_service),
+                          DRM_IRQ_TYPE, dev->devname, dev );
+       if ( ret < 0 ) {
+               down( &dev->struct_sem );
+               dev->irq = 0;
+               up( &dev->struct_sem );
+               return ret;
+       }
+
+                               /* After installing handler */
+       DRIVER_POSTINSTALL();
+
+       return 0;
+}
+
+int DRM(irq_uninstall)( drm_device_t *dev )
+{
+       int irq;
+
+       down( &dev->struct_sem );
+       irq = dev->irq;
+       dev->irq = 0;
+       up( &dev->struct_sem );
+
+       if ( !irq )
+               return -EINVAL;
+
+       DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, irq );
+
+       DRIVER_UNINSTALL();
+
+       free_irq( irq, dev );
+
+       return 0;
+}
+
+int DRM(control)( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_control_t ctl;
+
+       if ( copy_from_user( &ctl, (drm_control_t *)arg, sizeof(ctl) ) )
+               return -EFAULT;
+
+       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 -EINVAL;
+       }
+}
+
+#endif /* __HAVE_DMA_IRQ */
+
+#endif /* __HAVE_DMA */
diff --git a/drivers/char/drm/drm_drawable.h b/drivers/char/drm/drm_drawable.h
new file mode 100644 (file)
index 0000000..13e46b9
--- /dev/null
@@ -0,0 +1,51 @@
+/* drm_drawable.h -- IOCTLs for drawables -*- linux-c -*-
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int DRM(adddraw)(struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg)
+{
+       drm_draw_t draw;
+
+       draw.handle = 0;        /* NOOP */
+       DRM_DEBUG("%d\n", draw.handle);
+       if (copy_to_user((drm_draw_t *)arg, &draw, sizeof(draw)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(rmdraw)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
+{
+       return 0;               /* NOOP */
+}
diff --git a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
new file mode 100644 (file)
index 0000000..e1aff06
--- /dev/null
@@ -0,0 +1,1066 @@
+/* drm_drv.h -- Generic driver template -*- linux-c -*-
+ * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
+ *
+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * To use this template, you must at least define the following (samples
+ * given for the MGA driver):
+ *
+ * #define DRIVER_AUTHOR       "VA Linux Systems, Inc."
+ *
+ * #define DRIVER_NAME         "mga"
+ * #define DRIVER_DESC         "Matrox G200/G400"
+ * #define DRIVER_DATE         "20001127"
+ *
+ * #define DRIVER_MAJOR                2
+ * #define DRIVER_MINOR                0
+ * #define DRIVER_PATCHLEVEL   2
+ *
+ * #define DRIVER_IOCTL_COUNT  DRM_ARRAY_SIZE( mga_ioctls )
+ *
+ * #define DRM(x)              mga_##x
+ */
+
+#ifndef __MUST_HAVE_AGP
+#define __MUST_HAVE_AGP                        0
+#endif
+#ifndef __HAVE_CTX_BITMAP
+#define __HAVE_CTX_BITMAP              0
+#endif
+#ifndef __HAVE_DMA_IRQ
+#define __HAVE_DMA_IRQ                 0
+#endif
+#ifndef __HAVE_DMA_QUEUE
+#define __HAVE_DMA_QUEUE               0
+#endif
+#ifndef __HAVE_MULTIPLE_DMA_QUEUES
+#define __HAVE_MULTIPLE_DMA_QUEUES     0
+#endif
+#ifndef __HAVE_DMA_SCHEDULE
+#define __HAVE_DMA_SCHEDULE            0
+#endif
+#ifndef __HAVE_DMA_FLUSH
+#define __HAVE_DMA_FLUSH               0
+#endif
+#ifndef __HAVE_DMA_READY
+#define __HAVE_DMA_READY               0
+#endif
+#ifndef __HAVE_DMA_QUIESCENT
+#define __HAVE_DMA_QUIESCENT           0
+#endif
+#ifndef __HAVE_RELEASE
+#define __HAVE_RELEASE                 0
+#endif
+#ifndef __HAVE_COUNTERS
+#define __HAVE_COUNTERS                        0
+#endif
+#ifndef __HAVE_SG
+#define __HAVE_SG                      0
+#endif
+#ifndef __HAVE_KERNEL_CTX_SWITCH
+#define __HAVE_KERNEL_CTX_SWITCH       0
+#endif
+
+#ifndef DRIVER_PREINIT
+#define DRIVER_PREINIT()
+#endif
+#ifndef DRIVER_POSTINIT
+#define DRIVER_POSTINIT()
+#endif
+#ifndef DRIVER_PRERELEASE
+#define DRIVER_PRERELEASE()
+#endif
+#ifndef DRIVER_PRETAKEDOWN
+#define DRIVER_PRETAKEDOWN()
+#endif
+#ifndef DRIVER_POSTCLEANUP
+#define DRIVER_POSTCLEANUP()
+#endif
+#ifndef DRIVER_PRESETUP
+#define DRIVER_PRESETUP()
+#endif
+#ifndef DRIVER_POSTSETUP
+#define DRIVER_POSTSETUP()
+#endif
+#ifndef DRIVER_IOCTLS
+#define DRIVER_IOCTLS
+#endif
+#ifndef DRIVER_FOPS
+#if LINUX_VERSION_CODE >= 0x020400
+#define DRIVER_FOPS                            \
+static struct file_operations  DRM(fops) = {   \
+       owner:   THIS_MODULE,                   \
+       open:    DRM(open),                     \
+       flush:   DRM(flush),                    \
+       release: DRM(release),                  \
+       ioctl:   DRM(ioctl),                    \
+       mmap:    DRM(mmap),                     \
+       read:    DRM(read),                     \
+       fasync:  DRM(fasync),                   \
+       poll:    DRM(poll),                     \
+}
+#else
+#define DRIVER_FOPS                            \
+static struct file_operations  DRM(fops) = {   \
+       open:    DRM(open),                     \
+       flush:   DRM(flush),                    \
+       release: DRM(release),                  \
+       ioctl:   DRM(ioctl),                    \
+       mmap:    DRM(mmap),                     \
+       read:    DRM(read),                     \
+       fasync:  DRM(fasync),                   \
+       poll:    DRM(poll),                     \
+}
+#endif
+#endif
+
+
+/*
+ * The default number of instances (minor numbers) to initialize.
+ */
+#ifndef DRIVER_NUM_CARDS
+#define DRIVER_NUM_CARDS 1
+#endif
+
+static drm_device_t    *DRM(device);
+static int             *DRM(minor);
+static int             DRM(numdevs) = 0;
+
+DRIVER_FOPS;
+
+static drm_ioctl_desc_t                  DRM(ioctls)[] = {
+       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { DRM(version),     0, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { DRM(getunique),   0, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { DRM(getmagic),    0, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { DRM(irq_busid),   0, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP)]       = { DRM(getmap),      0, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT)]    = { DRM(getclient),   0, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS)]     = { DRM(getstats),    0, 0 },
+
+       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { DRM(setunique),   1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { DRM(block),       1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { DRM(unblock),     1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { DRM(authmagic),   1, 1 },
+
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { DRM(addmap),      1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP)]        = { DRM(rmmap),       1, 0 },
+
+#if __HAVE_CTX_BITMAP
+       [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = { DRM(setsareactx), 1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = { DRM(getsareactx), 1, 0 },
+#endif
+
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { DRM(addctx),      1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { DRM(rmctx),       1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { DRM(modctx),      1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { DRM(getctx),      1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { DRM(switchctx),   1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { DRM(newctx),      1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { DRM(resctx),      1, 0 },
+
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { DRM(adddraw),     1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { DRM(rmdraw),      1, 1 },
+
+       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]          = { DRM(lock),        1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { DRM(unlock),      1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { DRM(finish),      1, 0 },
+
+#if __HAVE_DMA
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { DRM(addbufs),     1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { DRM(markbufs),    1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { DRM(infobufs),    1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { DRM(mapbufs),     1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { DRM(freebufs),    1, 0 },
+
+       /* The DRM_IOCTL_DMA ioctl should be defined by the driver.
+        */
+#if __HAVE_DMA_IRQ
+       [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]       = { DRM(control),     1, 1 },
+#endif
+#endif
+
+#if __REALLY_HAVE_AGP
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { DRM(agp_acquire), 1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { DRM(agp_release), 1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { DRM(agp_enable),  1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { DRM(agp_info),    1, 0 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { DRM(agp_alloc),   1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { DRM(agp_free),    1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { DRM(agp_bind),    1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { DRM(agp_unbind),  1, 1 },
+#endif
+
+#if __HAVE_SG
+       [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC)]      = { DRM(sg_alloc),    1, 1 },
+       [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE)]       = { DRM(sg_free),     1, 1 },
+#endif
+
+       DRIVER_IOCTLS
+};
+
+#define DRIVER_IOCTL_COUNT     DRM_ARRAY_SIZE( DRM(ioctls) )
+
+#ifdef MODULE
+static char *drm_opts = NULL;
+#endif
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_PARM( drm_opts, "s" );
+
+static int DRM(setup)( drm_device_t *dev )
+{
+       int i;
+
+       DRIVER_PRESETUP();
+       atomic_set( &dev->ioctl_count, 0 );
+       atomic_set( &dev->vma_count, 0 );
+       dev->buf_use = 0;
+       atomic_set( &dev->buf_alloc, 0 );
+
+#if __HAVE_DMA
+       i = DRM(dma_setup)( dev );
+       if ( i < 0 )
+               return i;
+#endif
+
+       dev->counters  = 6 + __HAVE_COUNTERS;
+       dev->types[0]  = _DRM_STAT_LOCK;
+       dev->types[1]  = _DRM_STAT_OPENS;
+       dev->types[2]  = _DRM_STAT_CLOSES;
+       dev->types[3]  = _DRM_STAT_IOCTLS;
+       dev->types[4]  = _DRM_STAT_LOCKS;
+       dev->types[5]  = _DRM_STAT_UNLOCKS;
+#ifdef __HAVE_COUNTER6
+       dev->types[6]  = __HAVE_COUNTER6;
+#endif
+#ifdef __HAVE_COUNTER7
+       dev->types[7]  = __HAVE_COUNTER7;
+#endif
+#ifdef __HAVE_COUNTER8
+       dev->types[8]  = __HAVE_COUNTER8;
+#endif
+#ifdef __HAVE_COUNTER9
+       dev->types[9]  = __HAVE_COUNTER9;
+#endif
+#ifdef __HAVE_COUNTER10
+       dev->types[10] = __HAVE_COUNTER10;
+#endif
+#ifdef __HAVE_COUNTER11
+       dev->types[11] = __HAVE_COUNTER11;
+#endif
+#ifdef __HAVE_COUNTER12
+       dev->types[12] = __HAVE_COUNTER12;
+#endif
+#ifdef __HAVE_COUNTER13
+       dev->types[13] = __HAVE_COUNTER13;
+#endif
+#ifdef __HAVE_COUNTER14
+       dev->types[14] = __HAVE_COUNTER14;
+#endif
+#ifdef __HAVE_COUNTER15
+       dev->types[14] = __HAVE_COUNTER14;
+#endif
+
+       for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ )
+               atomic_set( &dev->counts[i], 0 );
+
+       for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+               dev->magiclist[i].head = NULL;
+               dev->magiclist[i].tail = NULL;
+       }
+
+       dev->maplist = DRM(alloc)(sizeof(*dev->maplist),
+                                 DRM_MEM_MAPS);
+       if(dev->maplist == NULL) return -ENOMEM;
+       memset(dev->maplist, 0, sizeof(*dev->maplist));
+       INIT_LIST_HEAD(&dev->maplist->head);
+       dev->map_count = 0;
+
+       dev->vmalist = NULL;
+       dev->lock.hw_lock = NULL;
+       init_waitqueue_head( &dev->lock.lock_queue );
+       dev->queue_count = 0;
+       dev->queue_reserved = 0;
+       dev->queue_slots = 0;
+       dev->queuelist = NULL;
+       dev->irq = 0;
+       dev->context_flag = 0;
+       dev->interrupt_flag = 0;
+       dev->dma_flag = 0;
+       dev->last_context = 0;
+       dev->last_switch = 0;
+       dev->last_checked = 0;
+       init_timer( &dev->timer );
+       init_waitqueue_head( &dev->context_wait );
+
+       dev->ctx_start = 0;
+       dev->lck_start = 0;
+
+       dev->buf_rp = dev->buf;
+       dev->buf_wp = dev->buf;
+       dev->buf_end = dev->buf + DRM_BSZ;
+       dev->buf_async = NULL;
+       init_waitqueue_head( &dev->buf_readers );
+       init_waitqueue_head( &dev->buf_writers );
+
+       DRM_DEBUG( "\n" );
+
+       /* The kernel's context could be created here, but is now created
+        * in drm_dma_enqueue.  This is more resource-efficient for
+        * hardware that does not do DMA, but may mean that
+        * drm_select_queue fails between the time the interrupt is
+        * initialized and the time the queues are initialized.
+        */
+       DRIVER_POSTSETUP();
+       return 0;
+}
+
+
+static int DRM(takedown)( drm_device_t *dev )
+{
+       drm_magic_entry_t *pt, *next;
+       drm_map_t *map;
+       drm_map_list_t *r_list;
+       struct list_head *list, *list_next;
+       drm_vma_entry_t *vma, *vma_next;
+       int i;
+
+       DRM_DEBUG( "\n" );
+
+       DRIVER_PRETAKEDOWN();
+#if __HAVE_DMA_IRQ
+       if ( dev->irq ) DRM(irq_uninstall)( dev );
+#endif
+
+       down( &dev->struct_sem );
+       del_timer( &dev->timer );
+
+       if ( dev->devname ) {
+               DRM(free)( dev->devname, strlen( dev->devname ) + 1,
+                          DRM_MEM_DRIVER );
+               dev->devname = NULL;
+       }
+
+       if ( dev->unique ) {
+               DRM(free)( dev->unique, strlen( dev->unique ) + 1,
+                          DRM_MEM_DRIVER );
+               dev->unique = NULL;
+               dev->unique_len = 0;
+       }
+                               /* Clear pid list */
+       for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) {
+               for ( pt = dev->magiclist[i].head ; pt ; pt = next ) {
+                       next = pt->next;
+                       DRM(free)( pt, sizeof(*pt), DRM_MEM_MAGIC );
+               }
+               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+       }
+
+#if __REALLY_HAVE_AGP
+                               /* Clear AGP information */
+       if ( dev->agp ) {
+               drm_agp_mem_t *entry;
+               drm_agp_mem_t *nexte;
+
+                               /* Remove AGP resources, but leave dev->agp
+                                   intact until drv_cleanup is called. */
+               for ( entry = dev->agp->memory ; entry ; entry = nexte ) {
+                       nexte = entry->next;
+                       if ( entry->bound ) DRM(unbind_agp)( entry->memory );
+                       DRM(free_agp)( entry->memory, entry->pages );
+                       DRM(free)( entry, sizeof(*entry), DRM_MEM_AGPLISTS );
+               }
+               dev->agp->memory = NULL;
+
+               if ( dev->agp->acquired ) DRM(agp_do_release)();
+
+               dev->agp->acquired = 0;
+               dev->agp->enabled  = 0;
+       }
+#endif
+
+                               /* Clear vma list (only built for debugging) */
+       if ( dev->vmalist ) {
+               for ( vma = dev->vmalist ; vma ; vma = vma_next ) {
+                       vma_next = vma->next;
+                       DRM(free)( vma, sizeof(*vma), DRM_MEM_VMAS );
+               }
+               dev->vmalist = NULL;
+       }
+
+       if( dev->maplist ) {
+               for(list = dev->maplist->head.next;
+                   list != &dev->maplist->head;
+                   list = list_next) {
+                       list_next = list->next;
+                       r_list = (drm_map_list_t *)list;
+                       map = r_list->map;
+                       DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
+                       if(!map) continue;
+
+                       switch ( map->type ) {
+                       case _DRM_REGISTERS:
+                       case _DRM_FRAME_BUFFER:
+#if __REALLY_HAVE_MTRR
+                               if ( map->mtrr >= 0 ) {
+                                       int retcode;
+                                       retcode = mtrr_del( map->mtrr,
+                                                           map->offset,
+                                                           map->size );
+                                       DRM_DEBUG( "mtrr_del=%d\n", retcode );
+                               }
+#endif
+                               DRM(ioremapfree)( map->handle, map->size );
+                               break;
+                       case _DRM_SHM:
+                               vfree(map->handle);
+                               break;
+
+                       case _DRM_AGP:
+                               /* Do nothing here, because this is all
+                                * handled in the AGP/GART driver.
+                                */
+                               break;
+                       case _DRM_SCATTER_GATHER:
+                               /* Handle it, but do nothing, if HAVE_SG
+                                * isn't defined.
+                                */
+#if __HAVE_SG
+                               if(dev->sg) {
+                                       DRM(sg_cleanup)(dev->sg);
+                                       dev->sg = NULL;
+                               }
+#endif
+                               break;
+                       }
+                       DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+               }
+               DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
+               dev->maplist = NULL;
+       }
+
+#if __HAVE_DMA_QUEUE || __HAVE_MULTIPLE_DMA_QUEUES
+       if ( dev->queuelist ) {
+               for ( i = 0 ; i < dev->queue_count ; i++ ) {
+                       DRM(waitlist_destroy)( &dev->queuelist[i]->waitlist );
+                       if ( dev->queuelist[i] ) {
+                               DRM(free)( dev->queuelist[i],
+                                         sizeof(*dev->queuelist[0]),
+                                         DRM_MEM_QUEUES );
+                               dev->queuelist[i] = NULL;
+                       }
+               }
+               DRM(free)( dev->queuelist,
+                         dev->queue_slots * sizeof(*dev->queuelist),
+                         DRM_MEM_QUEUES );
+               dev->queuelist = NULL;
+       }
+       dev->queue_count = 0;
+#endif
+
+#if __HAVE_DMA
+       DRM(dma_takedown)( dev );
+#endif
+       if ( dev->lock.hw_lock ) {
+               dev->lock.hw_lock = NULL; /* SHM removed */
+               dev->lock.pid = 0;
+               wake_up_interruptible( &dev->lock.lock_queue );
+       }
+       up( &dev->struct_sem );
+
+       return 0;
+}
+
+/*
+ * Figure out how many instances to initialize.
+ */
+static int drm_count_cards(void)
+{
+       int num = 0;
+#if defined(DRIVER_CARD_LIST)
+       int i;
+       drm_pci_list_t *l;
+       u16 device, vendor;
+       struct pci_dev *pdev = NULL;
+#endif
+
+       DRM_DEBUG( "\n" );
+
+#if defined(DRIVER_COUNT_CARDS)
+       num = DRIVER_COUNT_CARDS();
+#elif defined(DRIVER_CARD_LIST)
+       for (i = 0, l = DRIVER_CARD_LIST; l[i].vendor != 0; i++) {
+               pdev = NULL;
+               vendor = l[i].vendor;
+               device = l[i].device;
+               if(device == 0xffff) device = PCI_ANY_ID;
+               if(vendor == 0xffff) vendor = PCI_ANY_ID;
+               while ((pdev = pci_find_device(vendor, device, pdev))) {
+                       num++;
+               }
+       }
+#else
+       num = DRIVER_NUM_CARDS;
+#endif
+       DRM_DEBUG("numdevs = %d\n", num);
+       return num;
+}
+
+/* drm_init is called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported).
+ */
+static int __init drm_init( void )
+{
+
+       drm_device_t *dev;
+       int i;
+#if __HAVE_CTX_BITMAP
+       int retcode;
+#endif
+       DRM_DEBUG( "\n" );
+
+#ifdef MODULE
+       DRM(parse_options)( drm_opts );
+#endif
+
+       DRM(numdevs) = drm_count_cards();
+       /* Force at least one instance. */
+       if (DRM(numdevs) <= 0)
+               DRM(numdevs) = 1;
+
+       DRM(device) = kmalloc(sizeof(*DRM(device)) * DRM(numdevs), GFP_KERNEL);
+       if (!DRM(device)) {
+               return -ENOMEM;
+       }
+       DRM(minor) = kmalloc(sizeof(*DRM(minor)) * DRM(numdevs), GFP_KERNEL);
+       if (!DRM(minor)) {
+               kfree(DRM(device));
+               return -ENOMEM;
+       }
+
+       DRIVER_PREINIT();
+
+       DRM(mem_init)();
+
+       for (i = 0; i < DRM(numdevs); i++) {
+               dev = &(DRM(device)[i]);
+               memset( (void *)dev, 0, sizeof(*dev) );
+               dev->count_lock = SPIN_LOCK_UNLOCKED;
+               sema_init( &dev->struct_sem, 1 );
+
+               if ((DRM(minor)[i] = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
+                       return -EPERM;
+               dev->device = MKDEV(DRM_MAJOR, DRM(minor)[i] );
+               dev->name   = DRIVER_NAME;
+
+#if __REALLY_HAVE_AGP
+               dev->agp = DRM(agp_init)();
+#if __MUST_HAVE_AGP
+               if ( dev->agp == NULL ) {
+                       DRM_ERROR( "Cannot initialize the agpgart module.\n" );
+                       DRM(stub_unregister)(DRM(minor)[i]);
+                       DRM(takedown)( dev );
+                       return -ENOMEM;
+               }
+#endif
+#if __REALLY_HAVE_MTRR
+               if (dev->agp)
+                       dev->agp->agp_mtrr = mtrr_add( dev->agp->agp_info.aper_base,
+                                      dev->agp->agp_info.aper_size*1024*1024,
+                                      MTRR_TYPE_WRCOMB,
+                                      1 );
+#endif
+#endif
+
+#if __HAVE_CTX_BITMAP
+               retcode = DRM(ctxbitmap_init)( dev );
+               if( retcode ) {
+                       DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+                       DRM(stub_unregister)(DRM(minor)[i]);
+                       DRM(takedown)( dev );
+                       return retcode;
+               }
+#endif
+               DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
+                       DRIVER_NAME,
+                       DRIVER_MAJOR,
+                       DRIVER_MINOR,
+                       DRIVER_PATCHLEVEL,
+                       DRIVER_DATE,
+                       DRM(minor)[i] );
+       }
+
+       DRIVER_POSTINIT();
+
+       return 0;
+}
+
+/* drm_cleanup is called via cleanup_module at module unload time.
+ */
+static void __exit drm_cleanup( void )
+{
+       drm_device_t *dev;
+       int i;
+
+       DRM_DEBUG( "\n" );
+
+       for (i = DRM(numdevs) - 1; i >= 0; i--) {
+               dev = &(DRM(device)[i]);
+               if ( DRM(stub_unregister)(DRM(minor)[i]) ) {
+                       DRM_ERROR( "Cannot unload module\n" );
+               } else {
+                       DRM_DEBUG("minor %d unregistered\n", DRM(minor)[i]);
+                       if (i == 0) {
+                               DRM_INFO( "Module unloaded\n" );
+                       }
+               }
+#if __HAVE_CTX_BITMAP
+               DRM(ctxbitmap_cleanup)( dev );
+#endif
+
+#if __REALLY_HAVE_AGP && __REALLY_HAVE_MTRR
+               if ( dev->agp && dev->agp->agp_mtrr >= 0) {
+                       int retval;
+                       retval = mtrr_del( dev->agp->agp_mtrr,
+                                  dev->agp->agp_info.aper_base,
+                                  dev->agp->agp_info.aper_size*1024*1024 );
+                       DRM_DEBUG( "mtrr_del=%d\n", retval );
+               }
+#endif
+
+               DRM(takedown)( dev );
+
+#if __REALLY_HAVE_AGP
+               if ( dev->agp ) {
+                       DRM(agp_uninit)();
+                       DRM(free)( dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS );
+                       dev->agp = NULL;
+               }
+#endif
+       }
+       DRIVER_POSTCLEANUP();
+       kfree(DRM(minor));
+       kfree(DRM(device));
+       DRM(numdevs) = 0;
+}
+
+module_init( drm_init );
+module_exit( drm_cleanup );
+
+
+int DRM(version)( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
+{
+       drm_version_t version;
+       int len;
+
+       if ( copy_from_user( &version,
+                            (drm_version_t *)arg,
+                            sizeof(version) ) )
+               return -EFAULT;
+
+#define DRM_COPY( name, value )                                                \
+       len = strlen( value );                                          \
+       if ( len > name##_len ) len = name##_len;                       \
+       name##_len = strlen( value );                                   \
+       if ( len && name ) {                                            \
+               if ( copy_to_user( name, value, len ) )                 \
+                       return -EFAULT;                                 \
+       }
+
+       version.version_major = DRIVER_MAJOR;
+       version.version_minor = DRIVER_MINOR;
+       version.version_patchlevel = DRIVER_PATCHLEVEL;
+
+       DRM_COPY( version.name, DRIVER_NAME );
+       DRM_COPY( version.date, DRIVER_DATE );
+       DRM_COPY( version.desc, DRIVER_DESC );
+
+       if ( copy_to_user( (drm_version_t *)arg,
+                          &version,
+                          sizeof(version) ) )
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(open)( struct inode *inode, struct file *filp )
+{
+       drm_device_t *dev = NULL;
+       int retcode = 0;
+       int i;
+
+       for (i = 0; i < DRM(numdevs); i++) {
+               if (MINOR(inode->i_rdev) == DRM(minor)[i]) {
+                       dev = &(DRM(device)[i]);
+                       break;
+               }
+       }
+       if (!dev) {
+               return -ENODEV;
+       }
+
+       DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+       retcode = DRM(open_helper)( inode, filp, dev );
+       if ( !retcode ) {
+#if LINUX_VERSION_CODE < 0x020333
+               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+               atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
+               spin_lock( &dev->count_lock );
+               if ( !dev->open_count++ ) {
+                       spin_unlock( &dev->count_lock );
+                       return DRM(setup)( dev );
+               }
+               spin_unlock( &dev->count_lock );
+       }
+
+       return retcode;
+}
+
+int DRM(release)( struct inode *inode, struct file *filp )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev;
+       int retcode = 0;
+
+       lock_kernel();
+       dev = priv->dev;
+
+       DRM_DEBUG( "open_count = %d\n", dev->open_count );
+
+       DRIVER_PRERELEASE();
+
+       /* ========================================================
+        * Begin inline drm_release
+        */
+
+       DRM_DEBUG( "pid = %d, device = 0x%x, open_count = %d\n",
+                  current->pid, dev->device, dev->open_count );
+
+       if ( dev->lock.hw_lock &&
+            _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
+            dev->lock.pid == current->pid ) {
+               DRM_DEBUG( "Process %d dead, freeing lock for context %d\n",
+                          current->pid,
+                          _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+#if __HAVE_RELEASE
+               DRIVER_RELEASE();
+#endif
+               DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
+                               _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) );
+
+                               /* FIXME: may require heavy-handed reset of
+                                   hardware at this point, possibly
+                                   processed via a callback to the X
+                                   server. */
+       }
+#if __HAVE_RELEASE
+       else if ( dev->lock.hw_lock ) {
+               /* The lock is required to reclaim buffers */
+               DECLARE_WAITQUEUE( entry, current );
+               add_wait_queue( &dev->lock.lock_queue, &entry );
+               for (;;) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       if ( !dev->lock.hw_lock ) {
+                               /* Device has been unregistered */
+                               retcode = -EINTR;
+                               break;
+                       }
+                       if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
+                                            DRM_KERNEL_CONTEXT ) ) {
+                               dev->lock.pid       = priv->pid;
+                               dev->lock.lock_time = jiffies;
+                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+                               break;  /* Got lock */
+                       }
+                               /* Contention */
+#if 0
+                       atomic_inc( &dev->total_sleeps );
+#endif
+                       schedule();
+                       if ( signal_pending( current ) ) {
+                               retcode = -ERESTARTSYS;
+                               break;
+                       }
+               }
+               current->state = TASK_RUNNING;
+               remove_wait_queue( &dev->lock.lock_queue, &entry );
+               if( !retcode ) {
+                       DRIVER_RELEASE();
+                       DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
+                                       DRM_KERNEL_CONTEXT );
+               }
+       }
+#elif __HAVE_DMA
+       DRM(reclaim_buffers)( dev, priv->pid );
+#endif
+
+       DRM(fasync)( -1, filp, 0 );
+
+       down( &dev->struct_sem );
+       if ( priv->remove_auth_on_close == 1 ) {
+               drm_file_t *temp = dev->file_first;
+               while ( temp ) {
+                       temp->authenticated = 0;
+                       temp = temp->next;
+               }
+       }
+       if ( priv->prev ) {
+               priv->prev->next = priv->next;
+       } else {
+               dev->file_first  = priv->next;
+       }
+       if ( priv->next ) {
+               priv->next->prev = priv->prev;
+       } else {
+               dev->file_last   = priv->prev;
+       }
+       up( &dev->struct_sem );
+
+       DRM(free)( priv, sizeof(*priv), DRM_MEM_FILES );
+
+       /* ========================================================
+        * End inline drm_release
+        */
+
+#if LINUX_VERSION_CODE < 0x020333
+       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+       atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
+       spin_lock( &dev->count_lock );
+       if ( !--dev->open_count ) {
+               if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) {
+                       DRM_ERROR( "Device busy: %d %d\n",
+                                  atomic_read( &dev->ioctl_count ),
+                                  dev->blocked );
+                       spin_unlock( &dev->count_lock );
+                       unlock_kernel();
+                       return -EBUSY;
+               }
+               spin_unlock( &dev->count_lock );
+               unlock_kernel();
+               return DRM(takedown)( dev );
+       }
+       spin_unlock( &dev->count_lock );
+
+       unlock_kernel();
+       return retcode;
+}
+
+/* DRM(ioctl) is called whenever a process performs an ioctl on /dev/drm.
+ */
+int DRM(ioctl)( struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_ioctl_desc_t *ioctl;
+       drm_ioctl_t *func;
+       int nr = DRM_IOCTL_NR(cmd);
+       int retcode = 0;
+
+       atomic_inc( &dev->ioctl_count );
+       atomic_inc( &dev->counts[_DRM_STAT_IOCTLS] );
+       ++priv->ioctl_count;
+
+       DRM_DEBUG( "pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%x, auth=%d\n",
+                  current->pid, cmd, nr, dev->device, priv->authenticated );
+
+       if ( nr >= DRIVER_IOCTL_COUNT ) {
+               retcode = -EINVAL;
+       } else {
+               ioctl = &DRM(ioctls)[nr];
+               func = ioctl->func;
+
+               if ( !func ) {
+                       DRM_DEBUG( "no function\n" );
+                       retcode = -EINVAL;
+               } else if ( ( ioctl->root_only && !capable( CAP_SYS_ADMIN ) )||
+                           ( ioctl->auth_needed && !priv->authenticated ) ) {
+                       retcode = -EACCES;
+               } else {
+                       retcode = func( inode, filp, cmd, arg );
+               }
+       }
+
+       atomic_dec( &dev->ioctl_count );
+       return retcode;
+}
+
+int DRM(lock)( struct inode *inode, struct file *filp,
+              unsigned int cmd, unsigned long arg )
+{
+        drm_file_t *priv = filp->private_data;
+        drm_device_t *dev = priv->dev;
+        DECLARE_WAITQUEUE( entry, current );
+        drm_lock_t lock;
+        int ret = 0;
+#if __HAVE_MULTIPLE_DMA_QUEUES
+       drm_queue_t *q;
+#endif
+#if __HAVE_DMA_HISTOGRAM
+        cycles_t start;
+
+        dev->lck_start = start = get_cycles();
+#endif
+
+        if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
+               return -EFAULT;
+
+        if ( lock.context == DRM_KERNEL_CONTEXT ) {
+                DRM_ERROR( "Process %d using kernel context %d\n",
+                          current->pid, lock.context );
+                return -EINVAL;
+        }
+
+        DRM_DEBUG( "%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
+                  lock.context, current->pid,
+                  dev->lock.hw_lock->lock, lock.flags );
+
+#if __HAVE_DMA_QUEUE
+        if ( lock.context < 0 )
+                return -EINVAL;
+#elif __HAVE_MULTIPLE_DMA_QUEUES
+        if ( lock.context < 0 || lock.context >= dev->queue_count )
+                return -EINVAL;
+       q = dev->queuelist[lock.context];
+#endif
+
+#if __HAVE_DMA_FLUSH
+       ret = DRM(flush_block_and_flush)( dev, lock.context, lock.flags );
+#endif
+        if ( !ret ) {
+                add_wait_queue( &dev->lock.lock_queue, &entry );
+                for (;;) {
+                        current->state = TASK_INTERRUPTIBLE;
+                        if ( !dev->lock.hw_lock ) {
+                                /* Device has been unregistered */
+                                ret = -EINTR;
+                                break;
+                        }
+                        if ( DRM(lock_take)( &dev->lock.hw_lock->lock,
+                                            lock.context ) ) {
+                                dev->lock.pid       = current->pid;
+                                dev->lock.lock_time = jiffies;
+                                atomic_inc( &dev->counts[_DRM_STAT_LOCKS] );
+                                break;  /* Got lock */
+                        }
+
+                                /* Contention */
+                        schedule();
+                        if ( signal_pending( current ) ) {
+                                ret = -ERESTARTSYS;
+                                break;
+                        }
+                }
+                current->state = TASK_RUNNING;
+                remove_wait_queue( &dev->lock.lock_queue, &entry );
+        }
+
+#if __HAVE_DMA_FLUSH
+       DRM(flush_unblock)( dev, lock.context, lock.flags ); /* cleanup phase */
+#endif
+
+        if ( !ret ) {
+               sigemptyset( &dev->sigmask );
+               sigaddset( &dev->sigmask, SIGSTOP );
+               sigaddset( &dev->sigmask, SIGTSTP );
+               sigaddset( &dev->sigmask, SIGTTIN );
+               sigaddset( &dev->sigmask, SIGTTOU );
+               dev->sigdata.context = lock.context;
+               dev->sigdata.lock    = dev->lock.hw_lock;
+               block_all_signals( DRM(notifier),
+                                  &dev->sigdata, &dev->sigmask );
+
+#if __HAVE_DMA_READY
+                if ( lock.flags & _DRM_LOCK_READY ) {
+                       DRIVER_DMA_READY();
+               }
+#endif
+#if __HAVE_DMA_QUIESCENT
+                if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
+                       DRIVER_DMA_QUIESCENT();
+               }
+#endif
+#if __HAVE_KERNEL_CTX_SWITCH
+               if ( dev->last_context != lock.context ) {
+                       DRM(context_switch)(dev, dev->last_context,
+                                           lock.context);
+               }
+#endif
+        }
+
+        DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+
+#if __HAVE_DMA_HISTOGRAM
+        atomic_inc(&dev->histo.lacq[DRM(histogram_slot)(get_cycles()-start)]);
+#endif
+        return ret;
+}
+
+
+int DRM(unlock)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_lock_t lock;
+
+       if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
+               return -EFAULT;
+
+       if ( lock.context == DRM_KERNEL_CONTEXT ) {
+               DRM_ERROR( "Process %d using kernel context %d\n",
+                          current->pid, lock.context );
+               return -EINVAL;
+       }
+
+       atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
+
+       DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
+                           DRM_KERNEL_CONTEXT );
+#if __HAVE_DMA_SCHEDULE
+       DRM(dma_schedule)( dev, 1 );
+#endif
+
+       /* FIXME: Do we ever really need to check this???
+        */
+       if ( 1 /* !dev->context_flag */ ) {
+               if ( DRM(lock_free)( dev, &dev->lock.hw_lock->lock,
+                                    DRM_KERNEL_CONTEXT ) ) {
+                       DRM_ERROR( "\n" );
+               }
+       }
+
+       unblock_all_signals();
+       return 0;
+}
diff --git a/drivers/char/drm/drm_fops.h b/drivers/char/drm/drm_fops.h
new file mode 100644 (file)
index 0000000..3656c5e
--- /dev/null
@@ -0,0 +1,225 @@
+/* drm_fops.h -- File operations for DRM -*- linux-c -*-
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Daryll Strauss <daryll@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include <linux/poll.h>
+
+/* drm_open is called whenever a process opens /dev/drm. */
+
+int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
+{
+       kdev_t       minor = MINOR(inode->i_rdev);
+       drm_file_t   *priv;
+
+       if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
+       if (!DRM(cpu_valid)())        return -EINVAL;
+
+       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+
+       priv                = DRM(alloc)(sizeof(*priv), DRM_MEM_FILES);
+       if(!priv) return -ENOMEM;
+
+       memset(priv, 0, sizeof(*priv));
+       filp->private_data  = priv;
+       priv->uid           = current->euid;
+       priv->pid           = current->pid;
+       priv->minor         = minor;
+       priv->dev           = dev;
+       priv->ioctl_count   = 0;
+       priv->authenticated = capable(CAP_SYS_ADMIN);
+
+       down(&dev->struct_sem);
+       if (!dev->file_last) {
+               priv->next      = NULL;
+               priv->prev      = NULL;
+               dev->file_first = priv;
+               dev->file_last  = priv;
+       } else {
+               priv->next           = NULL;
+               priv->prev           = dev->file_last;
+               dev->file_last->next = priv;
+               dev->file_last       = priv;
+       }
+       up(&dev->struct_sem);
+
+#ifdef __alpha__
+       /*
+        * Default the hose
+        */
+       if (!dev->hose) {
+               struct pci_dev *pci_dev;
+               pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+               if (pci_dev) dev->hose = pci_dev->sysdata;
+               if (!dev->hose) {
+                       struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+                       if (b) dev->hose = b->sysdata;
+               }
+       }
+#endif
+
+       return 0;
+}
+
+int DRM(flush)(struct file *filp)
+{
+       drm_file_t    *priv   = filp->private_data;
+       drm_device_t  *dev    = priv->dev;
+
+       DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
+                 current->pid, dev->device, dev->open_count);
+       return 0;
+}
+
+int DRM(fasync)(int fd, struct file *filp, int on)
+{
+       drm_file_t    *priv   = filp->private_data;
+       drm_device_t  *dev    = priv->dev;
+       int           retcode;
+
+       DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device);
+       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+       if (retcode < 0) return retcode;
+       return 0;
+}
+
+
+/* The drm_read and drm_write_string code (especially that which manages
+   the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
+   DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
+
+ssize_t DRM(read)(struct file *filp, char *buf, size_t count, loff_t *off)
+{
+       drm_file_t    *priv   = filp->private_data;
+       drm_device_t  *dev    = priv->dev;
+       int           left;
+       int           avail;
+       int           send;
+       int           cur;
+
+       DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
+
+       while (dev->buf_rp == dev->buf_wp) {
+               DRM_DEBUG("  sleeping\n");
+               if (filp->f_flags & O_NONBLOCK) {
+                       return -EAGAIN;
+               }
+               interruptible_sleep_on(&dev->buf_readers);
+               if (signal_pending(current)) {
+                       DRM_DEBUG("  interrupted\n");
+                       return -ERESTARTSYS;
+               }
+               DRM_DEBUG("  awake\n");
+       }
+
+       left  = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+       avail = DRM_BSZ - left;
+       send  = DRM_MIN(avail, count);
+
+       while (send) {
+               if (dev->buf_wp > dev->buf_rp) {
+                       cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
+               } else {
+                       cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
+               }
+               if (copy_to_user(buf, dev->buf_rp, cur))
+                       return -EFAULT;
+               dev->buf_rp += cur;
+               if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
+               send -= cur;
+       }
+
+       wake_up_interruptible(&dev->buf_writers);
+       return DRM_MIN(avail, count);;
+}
+
+int DRM(write_string)(drm_device_t *dev, const char *s)
+{
+       int left   = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+       int send   = strlen(s);
+       int count;
+
+       DRM_DEBUG("%d left, %d to send (%p, %p)\n",
+                 left, send, dev->buf_rp, dev->buf_wp);
+
+       if (left == 1 || dev->buf_wp != dev->buf_rp) {
+               DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
+                         left,
+                         dev->buf_wp,
+                         dev->buf_rp);
+       }
+
+       while (send) {
+               if (dev->buf_wp >= dev->buf_rp) {
+                       count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
+                       if (count == left) --count; /* Leave a hole */
+               } else {
+                       count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
+               }
+               strncpy(dev->buf_wp, s, count);
+               dev->buf_wp += count;
+               if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
+               send -= count;
+       }
+
+#if LINUX_VERSION_CODE < 0x020315 && !defined(KILLFASYNCHASTHREEPARAMETERS)
+       /* The extra parameter to kill_fasync was added in 2.3.21, and is
+           _not_ present in _stock_ 2.2.14 and 2.2.15.  However, some
+           distributions patch 2.2.x kernels to add this parameter.  The
+           Makefile.linux attempts to detect this addition and defines
+           KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */
+       if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
+#else
+
+                               /* Parameter added in 2.3.21. */
+#if LINUX_VERSION_CODE < 0x020400
+       if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
+#else
+                               /* Type of first parameter changed in
+                                   Linux 2.4.0-test2... */
+       if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
+#endif
+#endif
+       DRM_DEBUG("waking\n");
+       wake_up_interruptible(&dev->buf_readers);
+       return 0;
+}
+
+unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
+{
+       drm_file_t   *priv = filp->private_data;
+       drm_device_t *dev  = priv->dev;
+
+       poll_wait(filp, &dev->buf_readers, wait);
+       if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM;
+       return 0;
+}
diff --git a/drivers/char/drm/drm_init.h b/drivers/char/drm/drm_init.h
new file mode 100644 (file)
index 0000000..2d6b6a3
--- /dev/null
@@ -0,0 +1,116 @@
+/* drm_init.h -- Setup/Cleanup for DRM -*- linux-c -*-
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if 0
+int DRM(flags) = DRM_FLAG_DEBUG;
+#else
+int DRM(flags) = 0;
+#endif
+
+/* drm_parse_option parses a single option.  See description for
+ * drm_parse_options for details.
+ */
+static void DRM(parse_option)(char *s)
+{
+       char *c, *r;
+
+       DRM_DEBUG("\"%s\"\n", s);
+       if (!s || !*s) return;
+       for (c = s; *c && *c != ':'; c++); /* find : or \0 */
+       if (*c) r = c + 1; else r = NULL;  /* remember remainder */
+       *c = '\0';                         /* terminate */
+       if (!strcmp(s, "noctx")) {
+               DRM(flags) |= DRM_FLAG_NOCTX;
+               DRM_INFO("Server-mediated context switching OFF\n");
+               return;
+       }
+       if (!strcmp(s, "debug")) {
+               DRM(flags) |= DRM_FLAG_DEBUG;
+               DRM_INFO("Debug messages ON\n");
+               return;
+       }
+       DRM_ERROR("\"%s\" is not a valid option\n", s);
+       return;
+}
+
+/* drm_parse_options parse the insmod "drm_opts=" options, or the command-line
+ * options passed to the kernel via LILO.  The grammar of the format is as
+ * follows:
+ *
+ * drm         ::= 'drm_opts=' option_list
+ * option_list ::= option [ ';' option_list ]
+ * option      ::= 'device:' major
+ *             |   'debug'
+ *             |   'noctx'
+ * major       ::= INTEGER
+ *
+ * Note that 's' contains option_list without the 'drm_opts=' part.
+ *
+ * device=major,minor specifies the device number used for /dev/drm
+ *       if major == 0 then the misc device is used
+ *       if major == 0 and minor == 0 then dynamic misc allocation is used
+ * debug=on specifies that debugging messages will be printk'd
+ * debug=trace specifies that each function call will be logged via printk
+ * debug=off turns off all debugging options
+ *
+ */
+
+void DRM(parse_options)(char *s)
+{
+       char *h, *t, *n;
+
+       DRM_DEBUG("\"%s\"\n", s ?: "");
+       if (!s || !*s) return;
+
+       for (h = t = n = s; h && *h; h = n) {
+               for (; *t && *t != ';'; t++);          /* find ; or \0 */
+               if (*t) n = t + 1; else n = NULL;      /* remember next */
+               *t = '\0';                             /* terminate */
+               DRM(parse_option)(h);                  /* parse */
+       }
+}
+
+/* drm_cpu_valid returns non-zero if the DRI will run on this CPU, and 0
+ * otherwise.
+ */
+int DRM(cpu_valid)(void)
+{
+#if defined(__i386__)
+       if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
+#endif
+#if defined(__sparc__) && !defined(__sparc_v9__)
+       return 0; /* No cmpxchg before v9 sparc. */
+#endif
+       return 1;
+}
diff --git a/drivers/char/drm/drm_ioctl.h b/drivers/char/drm/drm_ioctl.h
new file mode 100644 (file)
index 0000000..4712cbd
--- /dev/null
@@ -0,0 +1,234 @@
+/* drm_ioctl.h -- IOCTL processing for DRM -*- linux-c -*-
+ * Created: Fri Jan  8 09:01:26 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int DRM(irq_busid)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_irq_busid_t p;
+       struct pci_dev  *dev;
+
+       if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
+               return -EFAULT;
+       dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
+       if (dev) p.irq = dev->irq;
+       else     p.irq = 0;
+       DRM_DEBUG("%d:%d:%d => IRQ %d\n",
+                 p.busnum, p.devnum, p.funcnum, p.irq);
+       if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(getunique)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_unique_t     u;
+
+       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
+               return -EFAULT;
+       if (u.unique_len >= dev->unique_len) {
+               if (copy_to_user(u.unique, dev->unique, dev->unique_len))
+                       return -EFAULT;
+       }
+       u.unique_len = dev->unique_len;
+       if (copy_to_user((drm_unique_t *)arg, &u, sizeof(u)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(setunique)(struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_unique_t     u;
+
+       if (dev->unique_len || dev->unique) return -EBUSY;
+
+       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u))) return -EFAULT;
+
+       if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
+
+       dev->unique_len = u.unique_len;
+       dev->unique     = DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER);
+       if(!dev->unique) return -ENOMEM;
+       if (copy_from_user(dev->unique, u.unique, dev->unique_len))
+               return -EFAULT;
+
+       dev->unique[dev->unique_len] = '\0';
+
+       dev->devname = DRM(alloc)(strlen(dev->name) + strlen(dev->unique) + 2,
+                                 DRM_MEM_DRIVER);
+       if(!dev->devname) {
+               DRM(free)(dev->devname, sizeof(*dev->devname), DRM_MEM_DRIVER);
+               return -ENOMEM;
+       }
+       sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
+
+#ifdef __alpha__
+       do {
+               struct pci_dev *pci_dev;
+                int b, d, f;
+                char *p;
+                for(p = dev->unique; p && *p && *p != ':'; p++);
+                if (!p || !*p) break;
+                b = (int)simple_strtoul(p+1, &p, 10);
+                if (*p != ':') break;
+                d = (int)simple_strtoul(p+1, &p, 10);
+                if (*p != ':') break;
+                f = (int)simple_strtoul(p+1, &p, 10);
+                if (*p) break;
+                pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
+                if (pci_dev)
+                        dev->hose = pci_dev->sysdata;
+        } while(0);
+#endif
+
+       return 0;
+}
+
+
+int DRM(getmap)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t   *priv = filp->private_data;
+       drm_device_t *dev  = priv->dev;
+       drm_map_t    map;
+       drm_map_list_t *r_list = NULL;
+       struct list_head *list;
+       int          idx;
+       int          i;
+
+       if (copy_from_user(&map, (drm_map_t *)arg, sizeof(map)))
+               return -EFAULT;
+       idx = map.offset;
+
+       down(&dev->struct_sem);
+       if (idx < 0 || idx >= dev->map_count) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+
+       i = 0;
+       list_for_each(list, &dev->maplist->head) {
+               if(i == idx) {
+                       r_list = (drm_map_list_t *)list;
+                       break;
+               }
+               i++;
+       }
+       if(!r_list || !r_list->map) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+
+       map.offset = r_list->map->offset;
+       map.size   = r_list->map->size;
+       map.type   = r_list->map->type;
+       map.flags  = r_list->map->flags;
+       map.handle = r_list->map->handle;
+       map.mtrr   = r_list->map->mtrr;
+       up(&dev->struct_sem);
+
+       if (copy_to_user((drm_map_t *)arg, &map, sizeof(map))) return -EFAULT;
+       return 0;
+}
+
+int DRM(getclient)( struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg )
+{
+       drm_file_t   *priv = filp->private_data;
+       drm_device_t *dev  = priv->dev;
+       drm_client_t client;
+       drm_file_t   *pt;
+       int          idx;
+       int          i;
+
+       if (copy_from_user(&client, (drm_client_t *)arg, sizeof(client)))
+               return -EFAULT;
+       idx = client.idx;
+       down(&dev->struct_sem);
+       for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
+               ;
+
+       if (!pt) {
+               up(&dev->struct_sem);
+               return -EINVAL;
+       }
+       client.auth  = pt->authenticated;
+       client.pid   = pt->pid;
+       client.uid   = pt->uid;
+       client.magic = pt->magic;
+       client.iocs  = pt->ioctl_count;
+       up(&dev->struct_sem);
+
+       if (copy_to_user((drm_client_t *)arg, &client, sizeof(client)))
+               return -EFAULT;
+       return 0;
+}
+
+int DRM(getstats)( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
+{
+       drm_file_t   *priv = filp->private_data;
+       drm_device_t *dev  = priv->dev;
+       drm_stats_t  stats;
+       int          i;
+
+       memset(&stats, 0, sizeof(stats));
+       
+       down(&dev->struct_sem);
+
+       for (i = 0; i < dev->counters; i++) {
+               if (dev->types[i] == _DRM_STAT_LOCK)
+                       stats.data[i].value
+                               = (dev->lock.hw_lock
+                                  ? dev->lock.hw_lock->lock : 0);
+               else 
+                       stats.data[i].value = atomic_read(&dev->counts[i]);
+               stats.data[i].type  = dev->types[i];
+       }
+       
+       stats.count = dev->counters;
+
+       up(&dev->struct_sem);
+
+       if (copy_to_user((drm_stats_t *)arg, &stats, sizeof(stats)))
+               return -EFAULT;
+       return 0;
+}
diff --git a/drivers/char/drm/drm_lists.h b/drivers/char/drm/drm_lists.h
new file mode 100644 (file)
index 0000000..3ad487f
--- /dev/null
@@ -0,0 +1,230 @@
+/* drm_lists.h -- Buffer list handling routines -*- linux-c -*-
+ * Created: Mon Apr 19 20:54:22 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if __HAVE_DMA_WAITLIST
+
+int DRM(waitlist_create)(drm_waitlist_t *bl, int count)
+{
+       if (bl->count) return -EINVAL;
+
+       bl->bufs       = DRM(alloc)((bl->count + 2) * sizeof(*bl->bufs),
+                                   DRM_MEM_BUFLISTS);
+
+       if(!bl->bufs) return -ENOMEM;
+
+       bl->count      = count;
+       bl->rp         = bl->bufs;
+       bl->wp         = bl->bufs;
+       bl->end        = &bl->bufs[bl->count+1];
+       bl->write_lock = SPIN_LOCK_UNLOCKED;
+       bl->read_lock  = SPIN_LOCK_UNLOCKED;
+       return 0;
+}
+
+int DRM(waitlist_destroy)(drm_waitlist_t *bl)
+{
+       if (bl->rp != bl->wp) return -EINVAL;
+       if (bl->bufs) DRM(free)(bl->bufs,
+                               (bl->count + 2) * sizeof(*bl->bufs),
+                               DRM_MEM_BUFLISTS);
+       bl->count = 0;
+       bl->bufs  = NULL;
+       bl->rp    = NULL;
+       bl->wp    = NULL;
+       bl->end   = NULL;
+       return 0;
+}
+
+int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf)
+{
+       int           left;
+       unsigned long flags;
+
+       left = DRM_LEFTCOUNT(bl);
+       if (!left) {
+               DRM_ERROR("Overflow while adding buffer %d from pid %d\n",
+                         buf->idx, buf->pid);
+               return -EINVAL;
+       }
+#if __HAVE_DMA_HISTOGRAM
+       buf->time_queued = get_cycles();
+#endif
+       buf->list        = DRM_LIST_WAIT;
+
+       spin_lock_irqsave(&bl->write_lock, flags);
+       *bl->wp = buf;
+       if (++bl->wp >= bl->end) bl->wp = bl->bufs;
+       spin_unlock_irqrestore(&bl->write_lock, flags);
+
+       return 0;
+}
+
+drm_buf_t *DRM(waitlist_get)(drm_waitlist_t *bl)
+{
+       drm_buf_t     *buf;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bl->read_lock, flags);
+       buf = *bl->rp;
+       if (bl->rp == bl->wp) {
+               spin_unlock_irqrestore(&bl->read_lock, flags);
+               return NULL;
+       }
+       if (++bl->rp >= bl->end) bl->rp = bl->bufs;
+       spin_unlock_irqrestore(&bl->read_lock, flags);
+
+       return buf;
+}
+
+#endif /* __HAVE_DMA_WAITLIST */
+
+
+#if __HAVE_DMA_FREELIST
+
+int DRM(freelist_create)(drm_freelist_t *bl, int count)
+{
+       atomic_set(&bl->count, 0);
+       bl->next      = NULL;
+       init_waitqueue_head(&bl->waiting);
+       bl->low_mark  = 0;
+       bl->high_mark = 0;
+       atomic_set(&bl->wfh,   0);
+       bl->lock      = SPIN_LOCK_UNLOCKED;
+       ++bl->initialized;
+       return 0;
+}
+
+int DRM(freelist_destroy)(drm_freelist_t *bl)
+{
+       atomic_set(&bl->count, 0);
+       bl->next = NULL;
+       return 0;
+}
+
+int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
+{
+       drm_device_dma_t *dma  = dev->dma;
+
+       if (!dma) {
+               DRM_ERROR("No DMA support\n");
+               return 1;
+       }
+
+       if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) {
+               DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
+                         buf->idx, buf->waiting, buf->pending, buf->list);
+       }
+       if (!bl) return 1;
+#if __HAVE_DMA_HISTOGRAM
+       buf->time_freed = get_cycles();
+       DRM(histogram_compute)(dev, buf);
+#endif
+       buf->list       = DRM_LIST_FREE;
+
+       spin_lock(&bl->lock);
+       buf->next       = bl->next;
+       bl->next        = buf;
+       spin_unlock(&bl->lock);
+
+       atomic_inc(&bl->count);
+       if (atomic_read(&bl->count) > dma->buf_count) {
+               DRM_ERROR("%d of %d buffers free after addition of %d\n",
+                         atomic_read(&bl->count), dma->buf_count, buf->idx);
+               return 1;
+       }
+                               /* Check for high water mark */
+       if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
+               atomic_set(&bl->wfh, 0);
+               wake_up_interruptible(&bl->waiting);
+       }
+       return 0;
+}
+
+static drm_buf_t *DRM(freelist_try)(drm_freelist_t *bl)
+{
+       drm_buf_t         *buf;
+
+       if (!bl) return NULL;
+
+                               /* Get buffer */
+       spin_lock(&bl->lock);
+       if (!bl->next) {
+               spin_unlock(&bl->lock);
+               return NULL;
+       }
+       buf       = bl->next;
+       bl->next  = bl->next->next;
+       spin_unlock(&bl->lock);
+
+       atomic_dec(&bl->count);
+       buf->next = NULL;
+       buf->list = DRM_LIST_NONE;
+       if (buf->waiting || buf->pending) {
+               DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
+                         buf->idx, buf->waiting, buf->pending, buf->list);
+       }
+
+       return buf;
+}
+
+drm_buf_t *DRM(freelist_get)(drm_freelist_t *bl, int block)
+{
+       drm_buf_t         *buf  = NULL;
+       DECLARE_WAITQUEUE(entry, current);
+
+       if (!bl || !bl->initialized) return NULL;
+
+                               /* Check for low water mark */
+       if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
+               atomic_set(&bl->wfh, 1);
+       if (atomic_read(&bl->wfh)) {
+               if (block) {
+                       add_wait_queue(&bl->waiting, &entry);
+                       for (;;) {
+                               current->state = TASK_INTERRUPTIBLE;
+                               if (!atomic_read(&bl->wfh)
+                                   && (buf = DRM(freelist_try)(bl))) break;
+                               schedule();
+                               if (signal_pending(current)) break;
+                       }
+                       current->state = TASK_RUNNING;
+                       remove_wait_queue(&bl->waiting, &entry);
+               }
+               return buf;
+       }
+
+       return DRM(freelist_try)(bl);
+}
+
+#endif /* __HAVE_DMA_FREELIST */
diff --git a/drivers/char/drm/drm_lock.h b/drivers/char/drm/drm_lock.h
new file mode 100644 (file)
index 0000000..c10cfe2
--- /dev/null
@@ -0,0 +1,251 @@
+/* lock.c -- IOCTLs for locking -*- linux-c -*-
+ * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int DRM(block)(struct inode *inode, struct file *filp, unsigned int cmd,
+              unsigned long arg)
+{
+       DRM_DEBUG("\n");
+       return 0;
+}
+
+int DRM(unblock)(struct inode *inode, struct file *filp, unsigned int cmd,
+                unsigned long arg)
+{
+       DRM_DEBUG("\n");
+       return 0;
+}
+
+int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
+{
+       unsigned int old, new, prev;
+
+       do {
+               old = *lock;
+               if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+               else                      new = context | _DRM_LOCK_HELD;
+               prev = cmpxchg(lock, old, new);
+       } while (prev != old);
+       if (_DRM_LOCKING_CONTEXT(old) == context) {
+               if (old & _DRM_LOCK_HELD) {
+                       if (context != DRM_KERNEL_CONTEXT) {
+                               DRM_ERROR("%d holds heavyweight lock\n",
+                                         context);
+                       }
+                       return 0;
+               }
+       }
+       if (new == (context | _DRM_LOCK_HELD)) {
+                               /* Have lock */
+               return 1;
+       }
+       return 0;
+}
+
+/* This takes a lock forcibly and hands it to context. Should ONLY be used
+   inside *_unlock to give lock to kernel before calling *_dma_schedule. */
+int DRM(lock_transfer)(drm_device_t *dev,
+                      __volatile__ unsigned int *lock, unsigned int context)
+{
+       unsigned int old, new, prev;
+
+       dev->lock.pid = 0;
+       do {
+               old  = *lock;
+               new  = context | _DRM_LOCK_HELD;
+               prev = cmpxchg(lock, old, new);
+       } while (prev != old);
+       return 1;
+}
+
+int DRM(lock_free)(drm_device_t *dev,
+                  __volatile__ unsigned int *lock, unsigned int context)
+{
+       unsigned int old, new, prev;
+       pid_t        pid = dev->lock.pid;
+
+       dev->lock.pid = 0;
+       do {
+               old  = *lock;
+               new  = 0;
+               prev = cmpxchg(lock, old, new);
+       } while (prev != old);
+       if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+               DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
+                         context,
+                         _DRM_LOCKING_CONTEXT(old),
+                         pid);
+               return 1;
+       }
+       wake_up_interruptible(&dev->lock.lock_queue);
+       return 0;
+}
+
+static int DRM(flush_queue)(drm_device_t *dev, int context)
+{
+       DECLARE_WAITQUEUE(entry, current);
+       int               ret   = 0;
+       drm_queue_t       *q    = dev->queuelist[context];
+
+       DRM_DEBUG("\n");
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) > 1) {
+               atomic_inc(&q->block_write);
+               add_wait_queue(&q->flush_queue, &entry);
+               atomic_inc(&q->block_count);
+               for (;;) {
+                       current->state = TASK_INTERRUPTIBLE;
+                       if (!DRM_BUFCOUNT(&q->waitlist)) break;
+                       schedule();
+                       if (signal_pending(current)) {
+                               ret = -EINTR; /* Can't restart */
+                               break;
+                       }
+               }
+               atomic_dec(&q->block_count);
+               current->state = TASK_RUNNING;
+               remove_wait_queue(&q->flush_queue, &entry);
+       }
+       atomic_dec(&q->use_count);
+
+                               /* NOTE: block_write is still incremented!
+                                  Use drm_flush_unlock_queue to decrement. */
+       return ret;
+}
+
+static int DRM(flush_unblock_queue)(drm_device_t *dev, int context)
+{
+       drm_queue_t       *q    = dev->queuelist[context];
+
+       DRM_DEBUG("\n");
+
+       atomic_inc(&q->use_count);
+       if (atomic_read(&q->use_count) > 1) {
+               if (atomic_read(&q->block_write)) {
+                       atomic_dec(&q->block_write);
+                       wake_up_interruptible(&q->write_queue);
+               }
+       }
+       atomic_dec(&q->use_count);
+       return 0;
+}
+
+int DRM(flush_block_and_flush)(drm_device_t *dev, int context,
+                              drm_lock_flags_t flags)
+{
+       int ret = 0;
+       int i;
+
+       DRM_DEBUG("\n");
+
+       if (flags & _DRM_LOCK_FLUSH) {
+               ret = DRM(flush_queue)(dev, DRM_KERNEL_CONTEXT);
+               if (!ret) ret = DRM(flush_queue)(dev, context);
+       }
+       if (flags & _DRM_LOCK_FLUSH_ALL) {
+               for (i = 0; !ret && i < dev->queue_count; i++) {
+                       ret = DRM(flush_queue)(dev, i);
+               }
+       }
+       return ret;
+}
+
+int DRM(flush_unblock)(drm_device_t *dev, int context, drm_lock_flags_t flags)
+{
+       int ret = 0;
+       int i;
+
+       DRM_DEBUG("\n");
+
+       if (flags & _DRM_LOCK_FLUSH) {
+               ret = DRM(flush_unblock_queue)(dev, DRM_KERNEL_CONTEXT);
+               if (!ret) ret = DRM(flush_unblock_queue)(dev, context);
+       }
+       if (flags & _DRM_LOCK_FLUSH_ALL) {
+               for (i = 0; !ret && i < dev->queue_count; i++) {
+                       ret = DRM(flush_unblock_queue)(dev, i);
+               }
+       }
+
+       return ret;
+}
+
+int DRM(finish)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
+{
+       drm_file_t        *priv   = filp->private_data;
+       drm_device_t      *dev    = priv->dev;
+       int               ret     = 0;
+       drm_lock_t        lock;
+
+       DRM_DEBUG("\n");
+
+       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+               return -EFAULT;
+       ret = DRM(flush_block_and_flush)(dev, lock.context, lock.flags);
+       DRM(flush_unblock)(dev, lock.context, lock.flags);
+       return ret;
+}
+
+/* If we get here, it means that the process has called DRM_IOCTL_LOCK
+   without calling DRM_IOCTL_UNLOCK.
+
+   If the lock is not held, then let the signal proceed as usual.
+
+   If the lock is held, then set the contended flag and keep the signal
+   blocked.
+
+
+   Return 1 if the signal should be delivered normally.
+   Return 0 if the signal should be blocked.  */
+
+int DRM(notifier)(void *priv)
+{
+       drm_sigdata_t *s = (drm_sigdata_t *)priv;
+       unsigned int  old, new, prev;
+
+
+                               /* Allow signal delivery if lock isn't held */
+       if (!_DRM_LOCK_IS_HELD(s->lock->lock)
+           || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
+
+                               /* Otherwise, set flag to force call to
+                                   drmUnlock */
+       do {
+               old  = s->lock->lock;
+               new  = old | _DRM_LOCK_CONT;
+               prev = cmpxchg(&s->lock->lock, old, new);
+       } while (prev != old);
+       return 0;
+}
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
new file mode 100644 (file)
index 0000000..498937d
--- /dev/null
@@ -0,0 +1,459 @@
+/* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
+ * Created: Thu Feb  4 14:00:34 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include "drmP.h"
+#include <linux/wrapper.h>
+
+typedef struct drm_mem_stats {
+       const char        *name;
+       int               succeed_count;
+       int               free_count;
+       int               fail_count;
+       unsigned long     bytes_allocated;
+       unsigned long     bytes_freed;
+} drm_mem_stats_t;
+
+static spinlock_t        DRM(mem_lock)      = SPIN_LOCK_UNLOCKED;
+static unsigned long     DRM(ram_available) = 0; /* In pages */
+static unsigned long     DRM(ram_used)      = 0;
+static drm_mem_stats_t   DRM(mem_stats)[]   = {
+       [DRM_MEM_DMA]       = { "dmabufs"  },
+       [DRM_MEM_SAREA]     = { "sareas"   },
+       [DRM_MEM_DRIVER]    = { "driver"   },
+       [DRM_MEM_MAGIC]     = { "magic"    },
+       [DRM_MEM_IOCTLS]    = { "ioctltab" },
+       [DRM_MEM_MAPS]      = { "maplist"  },
+       [DRM_MEM_VMAS]      = { "vmalist"  },
+       [DRM_MEM_BUFS]      = { "buflist"  },
+       [DRM_MEM_SEGS]      = { "seglist"  },
+       [DRM_MEM_PAGES]     = { "pagelist" },
+       [DRM_MEM_FILES]     = { "files"    },
+       [DRM_MEM_QUEUES]    = { "queues"   },
+       [DRM_MEM_CMDS]      = { "commands" },
+       [DRM_MEM_MAPPINGS]  = { "mappings" },
+       [DRM_MEM_BUFLISTS]  = { "buflists" },
+       [DRM_MEM_AGPLISTS]  = { "agplist"  },
+       [DRM_MEM_SGLISTS]   = { "sglist"   },
+       [DRM_MEM_TOTALAGP]  = { "totalagp" },
+       [DRM_MEM_BOUNDAGP]  = { "boundagp" },
+       [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
+       [DRM_MEM_STUB]      = { "stub"     },
+       { NULL, 0, }            /* Last entry must be null */
+};
+
+void DRM(mem_init)(void)
+{
+       drm_mem_stats_t *mem;
+       struct sysinfo  si;
+
+       for (mem = DRM(mem_stats); mem->name; ++mem) {
+               mem->succeed_count   = 0;
+               mem->free_count      = 0;
+               mem->fail_count      = 0;
+               mem->bytes_allocated = 0;
+               mem->bytes_freed     = 0;
+       }
+
+       si_meminfo(&si);
+#if LINUX_VERSION_CODE < 0x020317
+                               /* Changed to page count in 2.3.23 */
+       DRM(ram_available) = si.totalram >> PAGE_SHIFT;
+#else
+       DRM(ram_available) = si.totalram;
+#endif
+       DRM(ram_used)      = 0;
+}
+
+/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+
+static int DRM(_mem_info)(char *buf, char **start, off_t offset,
+                         int request, int *eof, void *data)
+{
+       drm_mem_stats_t *pt;
+       int             len = 0;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *eof   = 0;
+       *start = &buf[offset];
+
+       DRM_PROC_PRINT("                  total counts                  "
+                      " |    outstanding  \n");
+       DRM_PROC_PRINT("type       alloc freed fail     bytes      freed"
+                      " | allocs      bytes\n\n");
+       DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
+                      "system", 0, 0, 0,
+                      DRM(ram_available) << (PAGE_SHIFT - 10));
+       DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
+                      "locked", 0, 0, 0, DRM(ram_used) >> 10);
+       DRM_PROC_PRINT("\n");
+       for (pt = DRM(mem_stats); pt->name; pt++) {
+               DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
+                              pt->name,
+                              pt->succeed_count,
+                              pt->free_count,
+                              pt->fail_count,
+                              pt->bytes_allocated,
+                              pt->bytes_freed,
+                              pt->succeed_count - pt->free_count,
+                              (long)pt->bytes_allocated
+                              - (long)pt->bytes_freed);
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+int DRM(mem_info)(char *buf, char **start, off_t offset,
+                 int len, int *eof, void *data)
+{
+       int ret;
+
+       spin_lock(&DRM(mem_lock));
+       ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
+       spin_unlock(&DRM(mem_lock));
+       return ret;
+}
+
+void *DRM(alloc)(size_t size, int area)
+{
+       void *pt;
+
+       if (!size) {
+               DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
+               return NULL;
+       }
+
+       if (!(pt = kmalloc(size, GFP_KERNEL))) {
+               spin_lock(&DRM(mem_lock));
+               ++DRM(mem_stats)[area].fail_count;
+               spin_unlock(&DRM(mem_lock));
+               return NULL;
+       }
+       spin_lock(&DRM(mem_lock));
+       ++DRM(mem_stats)[area].succeed_count;
+       DRM(mem_stats)[area].bytes_allocated += size;
+       spin_unlock(&DRM(mem_lock));
+       return pt;
+}
+
+void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
+{
+       void *pt;
+
+       if (!(pt = DRM(alloc)(size, area))) return NULL;
+       if (oldpt && oldsize) {
+               memcpy(pt, oldpt, oldsize);
+               DRM(free)(oldpt, oldsize, area);
+       }
+       return pt;
+}
+
+char *DRM(strdup)(const char *s, int area)
+{
+       char *pt;
+       int      length = s ? strlen(s) : 0;
+
+       if (!(pt = DRM(alloc)(length+1, area))) return NULL;
+       strcpy(pt, s);
+       return pt;
+}
+
+void DRM(strfree)(const char *s, int area)
+{
+       unsigned int size;
+
+       if (!s) return;
+
+       size = 1 + (s ? strlen(s) : 0);
+       DRM(free)((void *)s, size, area);
+}
+
+void DRM(free)(void *pt, size_t size, int area)
+{
+       int alloc_count;
+       int free_count;
+
+       if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+       else     kfree(pt);
+       spin_lock(&DRM(mem_lock));
+       DRM(mem_stats)[area].bytes_freed += size;
+       free_count  = ++DRM(mem_stats)[area].free_count;
+       alloc_count =   DRM(mem_stats)[area].succeed_count;
+       spin_unlock(&DRM(mem_lock));
+       if (free_count > alloc_count) {
+               DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+                             free_count, alloc_count);
+       }
+}
+
+unsigned long DRM(alloc_pages)(int order, int area)
+{
+       unsigned long address;
+       unsigned long bytes       = PAGE_SIZE << order;
+       unsigned long addr;
+       unsigned int  sz;
+
+       spin_lock(&DRM(mem_lock));
+       if ((DRM(ram_used) >> PAGE_SHIFT)
+           > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
+               spin_unlock(&DRM(mem_lock));
+               return 0;
+       }
+       spin_unlock(&DRM(mem_lock));
+
+       address = __get_free_pages(GFP_KERNEL, order);
+       if (!address) {
+               spin_lock(&DRM(mem_lock));
+               ++DRM(mem_stats)[area].fail_count;
+               spin_unlock(&DRM(mem_lock));
+               return 0;
+       }
+       spin_lock(&DRM(mem_lock));
+       ++DRM(mem_stats)[area].succeed_count;
+       DRM(mem_stats)[area].bytes_allocated += bytes;
+       DRM(ram_used)                        += bytes;
+       spin_unlock(&DRM(mem_lock));
+
+
+                               /* Zero outside the lock */
+       memset((void *)address, 0, bytes);
+
+                               /* Reserve */
+       for (addr = address, sz = bytes;
+            sz > 0;
+            addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+#if LINUX_VERSION_CODE >= 0x020400
+                               /* Argument type changed in 2.4.0-test6/pre8 */
+               mem_map_reserve(virt_to_page(addr));
+#else
+               mem_map_reserve(MAP_NR(addr));
+#endif
+       }
+
+       return address;
+}
+
+void DRM(free_pages)(unsigned long address, int order, int area)
+{
+       unsigned long bytes = PAGE_SIZE << order;
+       int               alloc_count;
+       int               free_count;
+       unsigned long addr;
+       unsigned int  sz;
+
+       if (!address) {
+               DRM_MEM_ERROR(area, "Attempt to free address 0\n");
+       } else {
+                               /* Unreserve */
+               for (addr = address, sz = bytes;
+                    sz > 0;
+                    addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+#if LINUX_VERSION_CODE >= 0x020400
+                               /* Argument type changed in 2.4.0-test6/pre8 */
+                       mem_map_unreserve(virt_to_page(addr));
+#else
+                       mem_map_unreserve(MAP_NR(addr));
+#endif
+               }
+               free_pages(address, order);
+       }
+
+       spin_lock(&DRM(mem_lock));
+       free_count  = ++DRM(mem_stats)[area].free_count;
+       alloc_count =   DRM(mem_stats)[area].succeed_count;
+       DRM(mem_stats)[area].bytes_freed += bytes;
+       DRM(ram_used)                    -= bytes;
+       spin_unlock(&DRM(mem_lock));
+       if (free_count > alloc_count) {
+               DRM_MEM_ERROR(area,
+                             "Excess frees: %d frees, %d allocs\n",
+                             free_count, alloc_count);
+       }
+}
+
+void *DRM(ioremap)(unsigned long offset, unsigned long size)
+{
+       void *pt;
+
+       if (!size) {
+               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+                             "Mapping 0 bytes at 0x%08lx\n", offset);
+               return NULL;
+       }
+
+       if (!(pt = ioremap(offset, size))) {
+               spin_lock(&DRM(mem_lock));
+               ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+               spin_unlock(&DRM(mem_lock));
+               return NULL;
+       }
+       spin_lock(&DRM(mem_lock));
+       ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+       DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+       spin_unlock(&DRM(mem_lock));
+       return pt;
+}
+
+void DRM(ioremapfree)(void *pt, unsigned long size)
+{
+       int alloc_count;
+       int free_count;
+
+       if (!pt)
+               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+                             "Attempt to free NULL pointer\n");
+       else
+               iounmap(pt);
+
+       spin_lock(&DRM(mem_lock));
+       DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
+       free_count  = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+       alloc_count =   DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+       spin_unlock(&DRM(mem_lock));
+       if (free_count > alloc_count) {
+               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+                             "Excess frees: %d frees, %d allocs\n",
+                             free_count, alloc_count);
+       }
+}
+
+#if __REALLY_HAVE_AGP
+
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
+{
+       agp_memory *handle;
+
+       if (!pages) {
+               DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
+               return NULL;
+       }
+
+       if ((handle = DRM(agp_allocate_memory)(pages, type))) {
+               spin_lock(&DRM(mem_lock));
+               ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+               DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+                       += pages << PAGE_SHIFT;
+               spin_unlock(&DRM(mem_lock));
+               return handle;
+       }
+       spin_lock(&DRM(mem_lock));
+       ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
+       spin_unlock(&DRM(mem_lock));
+       return NULL;
+}
+
+int DRM(free_agp)(agp_memory *handle, int pages)
+{
+       int           alloc_count;
+       int           free_count;
+       int           retval = -EINVAL;
+
+       if (!handle) {
+               DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+                             "Attempt to free NULL AGP handle\n");
+               return retval;;
+       }
+
+       if (DRM(agp_free_memory)(handle)) {
+               spin_lock(&DRM(mem_lock));
+               free_count  = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
+               alloc_count =   DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
+               DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+                       += pages << PAGE_SHIFT;
+               spin_unlock(&DRM(mem_lock));
+               if (free_count > alloc_count) {
+                       DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
+                                     "Excess frees: %d frees, %d allocs\n",
+                                     free_count, alloc_count);
+               }
+               return 0;
+       }
+       return retval;
+}
+
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
+{
+       int retcode = -EINVAL;
+
+       if (!handle) {
+               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+                             "Attempt to bind NULL AGP handle\n");
+               return retcode;
+       }
+
+       if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
+               spin_lock(&DRM(mem_lock));
+               ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+               DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+                       += handle->page_count << PAGE_SHIFT;
+               spin_unlock(&DRM(mem_lock));
+               return retcode;
+       }
+       spin_lock(&DRM(mem_lock));
+       ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
+       spin_unlock(&DRM(mem_lock));
+       return retcode;
+}
+
+int DRM(unbind_agp)(agp_memory *handle)
+{
+       int alloc_count;
+       int free_count;
+       int retcode = -EINVAL;
+
+       if (!handle) {
+               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+                             "Attempt to unbind NULL AGP handle\n");
+               return retcode;
+       }
+
+       if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
+       spin_lock(&DRM(mem_lock));
+       free_count  = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
+       alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
+       DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+               += handle->page_count << PAGE_SHIFT;
+       spin_unlock(&DRM(mem_lock));
+       if (free_count > alloc_count) {
+               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
+                             "Excess frees: %d frees, %d allocs\n",
+                             free_count, alloc_count);
+       }
+       return retcode;
+}
+#endif
diff --git a/drivers/char/drm/drm_proc.h b/drivers/char/drm/drm_proc.h
new file mode 100644 (file)
index 0000000..f65f42b
--- /dev/null
@@ -0,0 +1,630 @@
+/* drm_proc.h -- /proc support for DRM -*- linux-c -*-
+ * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ *
+ * Acknowledgements:
+ *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
+ *    the problem with the proc files not outputting all their information.
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static int        DRM(name_info)(char *buf, char **start, off_t offset,
+                                 int request, int *eof, void *data);
+static int        DRM(vm_info)(char *buf, char **start, off_t offset,
+                               int request, int *eof, void *data);
+static int        DRM(clients_info)(char *buf, char **start, off_t offset,
+                                    int request, int *eof, void *data);
+static int        DRM(queues_info)(char *buf, char **start, off_t offset,
+                                   int request, int *eof, void *data);
+static int        DRM(bufs_info)(char *buf, char **start, off_t offset,
+                                 int request, int *eof, void *data);
+#if DRM_DEBUG_CODE
+static int        DRM(vma_info)(char *buf, char **start, off_t offset,
+                                int request, int *eof, void *data);
+#endif
+#if __HAVE_DMA_HISTOGRAM
+static int        DRM(histo_info)(char *buf, char **start, off_t offset,
+                                  int request, int *eof, void *data);
+#endif
+
+struct drm_proc_list {
+       const char *name;
+       int        (*f)(char *, char **, off_t, int, int *, void *);
+} DRM(proc_list)[] = {
+       { "name",    DRM(name_info)    },
+       { "mem",     DRM(mem_info)     },
+       { "vm",      DRM(vm_info)      },
+       { "clients", DRM(clients_info) },
+       { "queues",  DRM(queues_info)  },
+       { "bufs",    DRM(bufs_info)    },
+#if DRM_DEBUG_CODE
+       { "vma",     DRM(vma_info)     },
+#endif
+#if __HAVE_DMA_HISTOGRAM
+       { "histo",   DRM(histo_info)   },
+#endif
+};
+#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
+
+struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
+                                     struct proc_dir_entry *root,
+                                     struct proc_dir_entry **dev_root)
+{
+       struct proc_dir_entry *ent;
+       int                   i, j;
+       char                  name[64];
+
+       if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
+       if (!root) {
+               DRM_ERROR("Cannot create /proc/dri\n");
+               return NULL;
+       }
+
+       sprintf(name, "%d", minor);
+       *dev_root = create_proc_entry(name, S_IFDIR, root);
+       if (!*dev_root) {
+               DRM_ERROR("Cannot create /proc/%s\n", name);
+               return NULL;
+       }
+
+       for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+               ent = create_proc_entry(DRM(proc_list)[i].name,
+                                       S_IFREG|S_IRUGO, *dev_root);
+               if (!ent) {
+                       DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
+                                 name, DRM(proc_list)[i].name);
+                       for (j = 0; j < i; j++)
+                               remove_proc_entry(DRM(proc_list)[i].name,
+                                                 *dev_root);
+                       remove_proc_entry(name, root);
+                       if (!minor) remove_proc_entry("dri", NULL);
+                       return NULL;
+               }
+               ent->read_proc = DRM(proc_list)[i].f;
+               ent->data      = dev;
+       }
+
+       return root;
+}
+
+
+int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
+                     struct proc_dir_entry *dev_root)
+{
+       int  i;
+       char name[64];
+
+       if (!root || !dev_root) return 0;
+
+       for (i = 0; i < DRM_PROC_ENTRIES; i++)
+               remove_proc_entry(DRM(proc_list)[i].name, dev_root);
+       sprintf(name, "%d", minor);
+       remove_proc_entry(name, root);
+       if (!minor) remove_proc_entry("dri", NULL);
+
+       return 0;
+}
+
+static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
+                         int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          len  = 0;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       if (dev->unique) {
+               DRM_PROC_PRINT("%s 0x%x %s\n",
+                              dev->name, dev->device, dev->unique);
+       } else {
+               DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
+                        int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          len  = 0;
+       drm_map_t    *map;
+       drm_map_list_t *r_list;
+       struct list_head *list;
+
+                               /* Hardcoded from _DRM_FRAME_BUFFER,
+                                   _DRM_REGISTERS, _DRM_SHM, and
+                                   _DRM_AGP. */
+       const char   *types[] = { "FB", "REG", "SHM", "AGP" };
+       const char   *type;
+       int          i;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT("slot     offset       size type flags    "
+                      "address mtrr\n\n");
+       i = 0;
+       list_for_each(list, &dev->maplist->head) {
+               r_list = (drm_map_list_t *)list;
+               map = r_list->map;
+               if(!map) continue;
+               if (map->type < 0 || map->type > 3) type = "??";
+               else                                type = types[map->type];
+               DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
+                              i,
+                              map->offset,
+                              map->size,
+                              type,
+                              map->flags,
+                              (unsigned long)map->handle);
+               if (map->mtrr < 0) {
+                       DRM_PROC_PRINT("none\n");
+               } else {
+                       DRM_PROC_PRINT("%4d\n", map->mtrr);
+               }
+               i++;
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
+                       int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+
+
+static int DRM(_queues_info)(char *buf, char **start, off_t offset,
+                            int request, int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          len  = 0;
+       int          i;
+       drm_queue_t  *q;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT("  ctx/flags   use   fin"
+                      "   blk/rw/rwf  wait    flushed     queued"
+                      "      locks\n\n");
+       for (i = 0; i < dev->queue_count; i++) {
+               q = dev->queuelist[i];
+               atomic_inc(&q->use_count);
+               DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
+                                  "%5d/0x%03x %5d %5d"
+                                  " %5d/%c%c/%c%c%c %5Zd\n",
+                                  i,
+                                  q->flags,
+                                  atomic_read(&q->use_count),
+                                  atomic_read(&q->finalization),
+                                  atomic_read(&q->block_count),
+                                  atomic_read(&q->block_read) ? 'r' : '-',
+                                  atomic_read(&q->block_write) ? 'w' : '-',
+                                  waitqueue_active(&q->read_queue) ? 'r':'-',
+                                  waitqueue_active(&q->write_queue) ? 'w':'-',
+                                  waitqueue_active(&q->flush_queue) ? 'f':'-',
+                                  DRM_BUFCOUNT(&q->waitlist));
+               atomic_dec(&q->use_count);
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
+                           int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+
+/* drm_bufs_info is called whenever a process reads
+   /dev/dri/<dev>/bufs. */
+
+static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
+                          int *eof, void *data)
+{
+       drm_device_t     *dev = (drm_device_t *)data;
+       int              len  = 0;
+       drm_device_dma_t *dma = dev->dma;
+       int              i;
+
+       if (!dma || offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT(" o     size count  free  segs pages    kB\n\n");
+       for (i = 0; i <= DRM_MAX_ORDER; i++) {
+               if (dma->bufs[i].buf_count)
+                       DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
+                                      i,
+                                      dma->bufs[i].buf_size,
+                                      dma->bufs[i].buf_count,
+                                      atomic_read(&dma->bufs[i]
+                                                  .freelist.count),
+                                      dma->bufs[i].seg_count,
+                                      dma->bufs[i].seg_count
+                                      *(1 << dma->bufs[i].page_order),
+                                      (dma->bufs[i].seg_count
+                                       * (1 << dma->bufs[i].page_order))
+                                      * PAGE_SIZE / 1024);
+       }
+       DRM_PROC_PRINT("\n");
+       for (i = 0; i < dma->buf_count; i++) {
+               if (i && !(i%32)) DRM_PROC_PRINT("\n");
+               DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+       }
+       DRM_PROC_PRINT("\n");
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
+                         int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+
+
+static int DRM(_clients_info)(char *buf, char **start, off_t offset,
+                             int request, int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          len  = 0;
+       drm_file_t   *priv;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT("a dev   pid    uid      magic     ioctls\n\n");
+       for (priv = dev->file_first; priv; priv = priv->next) {
+               DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
+                              priv->authenticated ? 'y' : 'n',
+                              priv->minor,
+                              priv->pid,
+                              priv->uid,
+                              priv->magic,
+                              priv->ioctl_count);
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(clients_info)(char *buf, char **start, off_t offset,
+                            int request, int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+
+#if DRM_DEBUG_CODE
+
+#define DRM_VMA_VERBOSE 0
+
+static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
+                         int *eof, void *data)
+{
+       drm_device_t          *dev = (drm_device_t *)data;
+       int                   len  = 0;
+       drm_vma_entry_t       *pt;
+       struct vm_area_struct *vma;
+#if DRM_VMA_VERBOSE
+       unsigned long         i;
+       unsigned long         address;
+       pgd_t                 *pgd;
+       pmd_t                 *pmd;
+       pte_t                 *pte;
+#endif
+#if defined(__i386__)
+       unsigned int          pgprot;
+#endif
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+                      atomic_read(&dev->vma_count),
+                      high_memory, virt_to_phys(high_memory));
+       for (pt = dev->vmalist; pt; pt = pt->next) {
+               if (!(vma = pt->vma)) continue;
+               DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+                              pt->pid,
+                              vma->vm_start,
+                              vma->vm_end,
+                              vma->vm_flags & VM_READ     ? 'r' : '-',
+                              vma->vm_flags & VM_WRITE    ? 'w' : '-',
+                              vma->vm_flags & VM_EXEC     ? 'x' : '-',
+                              vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+                              vma->vm_flags & VM_LOCKED   ? 'l' : '-',
+                              vma->vm_flags & VM_IO       ? 'i' : '-',
+                              VM_OFFSET(vma));
+
+#if defined(__i386__)
+               pgprot = pgprot_val(vma->vm_page_prot);
+               DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+                              pgprot & _PAGE_PRESENT  ? 'p' : '-',
+                              pgprot & _PAGE_RW       ? 'w' : 'r',
+                              pgprot & _PAGE_USER     ? 'u' : 's',
+                              pgprot & _PAGE_PWT      ? 't' : 'b',
+                              pgprot & _PAGE_PCD      ? 'u' : 'c',
+                              pgprot & _PAGE_ACCESSED ? 'a' : '-',
+                              pgprot & _PAGE_DIRTY    ? 'd' : '-',
+                              pgprot & _PAGE_PSE      ? 'm' : 'k',
+                              pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
+#endif
+               DRM_PROC_PRINT("\n");
+#if 0
+               for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
+                       pgd = pgd_offset(vma->vm_mm, i);
+                       pmd = pmd_offset(pgd, i);
+                       pte = pte_offset(pmd, i);
+                       if (pte_present(*pte)) {
+                               address = __pa(pte_page(*pte))
+                                       + (i & (PAGE_SIZE-1));
+                               DRM_PROC_PRINT("      0x%08lx -> 0x%08lx"
+                                              " %c%c%c%c%c\n",
+                                              i,
+                                              address,
+                                              pte_read(*pte)  ? 'r' : '-',
+                                              pte_write(*pte) ? 'w' : '-',
+                                              pte_exec(*pte)  ? 'x' : '-',
+                                              pte_dirty(*pte) ? 'd' : '-',
+                                              pte_young(*pte) ? 'a' : '-' );
+                       } else {
+                               DRM_PROC_PRINT("      0x%08lx\n", i);
+                       }
+               }
+#endif
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
+                        int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+#endif
+
+
+#if __HAVE_DMA_HISTOGRAM
+static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request,
+                           int *eof, void *data)
+{
+       drm_device_t     *dev = (drm_device_t *)data;
+       int              len  = 0;
+       drm_device_dma_t *dma = dev->dma;
+       int              i;
+       unsigned long    slot_value = DRM_DMA_HISTOGRAM_INITIAL;
+       unsigned long    prev_value = 0;
+       drm_buf_t        *buffer;
+
+       if (offset > DRM_PROC_LIMIT) {
+               *eof = 1;
+               return 0;
+       }
+
+       *start = &buf[offset];
+       *eof   = 0;
+
+       DRM_PROC_PRINT("general statistics:\n");
+       DRM_PROC_PRINT("total    %10u\n", atomic_read(&dev->histo.total));
+       DRM_PROC_PRINT("open     %10u\n",
+                      atomic_read(&dev->counts[_DRM_STAT_OPENS]));
+       DRM_PROC_PRINT("close    %10u\n",
+                      atomic_read(&dev->counts[_DRM_STAT_CLOSES]));
+       DRM_PROC_PRINT("ioctl    %10u\n",
+                      atomic_read(&dev->counts[_DRM_STAT_IOCTLS]));
+
+       DRM_PROC_PRINT("\nlock statistics:\n");
+       DRM_PROC_PRINT("locks    %10u\n",
+                      atomic_read(&dev->counts[_DRM_STAT_LOCKS]));
+       DRM_PROC_PRINT("unlocks  %10u\n",
+                      atomic_read(&dev->counts[_DRM_STAT_UNLOCKS]));
+
+       if (dma) {
+#if 0
+               DRM_PROC_PRINT("\ndma statistics:\n");
+               DRM_PROC_PRINT("prio     %10u\n",
+                              atomic_read(&dma->total_prio));
+               DRM_PROC_PRINT("bytes    %10u\n",
+                              atomic_read(&dma->total_bytes));
+               DRM_PROC_PRINT("dmas     %10u\n",
+                              atomic_read(&dma->total_dmas));
+               DRM_PROC_PRINT("missed:\n");
+               DRM_PROC_PRINT("  dma    %10u\n",
+                              atomic_read(&dma->total_missed_dma));
+               DRM_PROC_PRINT("  lock   %10u\n",
+                              atomic_read(&dma->total_missed_lock));
+               DRM_PROC_PRINT("  free   %10u\n",
+                              atomic_read(&dma->total_missed_free));
+               DRM_PROC_PRINT("  sched  %10u\n",
+                              atomic_read(&dma->total_missed_sched));
+               DRM_PROC_PRINT("tried    %10u\n",
+                              atomic_read(&dma->total_tried));
+               DRM_PROC_PRINT("hit      %10u\n",
+                              atomic_read(&dma->total_hit));
+               DRM_PROC_PRINT("lost     %10u\n",
+                              atomic_read(&dma->total_lost));
+#endif
+
+               buffer = dma->next_buffer;
+               if (buffer) {
+                       DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx);
+               } else {
+                       DRM_PROC_PRINT("next_buffer    none\n");
+               }
+               buffer = dma->this_buffer;
+               if (buffer) {
+                       DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx);
+               } else {
+                       DRM_PROC_PRINT("this_buffer    none\n");
+               }
+       }
+
+
+       DRM_PROC_PRINT("\nvalues:\n");
+       if (dev->lock.hw_lock) {
+               DRM_PROC_PRINT("lock           0x%08x\n",
+                              dev->lock.hw_lock->lock);
+       } else {
+               DRM_PROC_PRINT("lock                 none\n");
+       }
+       DRM_PROC_PRINT("context_flag   0x%08lx\n", dev->context_flag);
+       DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
+       DRM_PROC_PRINT("dma_flag       0x%08lx\n", dev->dma_flag);
+
+       DRM_PROC_PRINT("queue_count    %10d\n",  dev->queue_count);
+       DRM_PROC_PRINT("last_context   %10d\n",  dev->last_context);
+       DRM_PROC_PRINT("last_switch    %10lu\n", dev->last_switch);
+       DRM_PROC_PRINT("last_checked   %10d\n",  dev->last_checked);
+
+
+       DRM_PROC_PRINT("\n                     q2d        d2c        c2f"
+                      "        q2c        q2f        dma        sch"
+                      "        ctx       lacq       lhld\n\n");
+       for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
+               DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
+                              " %10u %10u %10u %10u %10u\n",
+                              i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
+                              i == DRM_DMA_HISTOGRAM_SLOTS - 1
+                              ? prev_value : slot_value ,
+
+                              atomic_read(&dev->histo
+                                          .queued_to_dispatched[i]),
+                              atomic_read(&dev->histo
+                                          .dispatched_to_completed[i]),
+                              atomic_read(&dev->histo
+                                          .completed_to_freed[i]),
+
+                              atomic_read(&dev->histo
+                                          .queued_to_completed[i]),
+                              atomic_read(&dev->histo
+                                          .queued_to_freed[i]),
+                              atomic_read(&dev->histo.dma[i]),
+                              atomic_read(&dev->histo.schedule[i]),
+                              atomic_read(&dev->histo.ctx[i]),
+                              atomic_read(&dev->histo.lacq[i]),
+                              atomic_read(&dev->histo.lhld[i]));
+               prev_value = slot_value;
+               slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
+       }
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
+}
+
+static int DRM(histo_info)(char *buf, char **start, off_t offset, int request,
+                          int *eof, void *data)
+{
+       drm_device_t *dev = (drm_device_t *)data;
+       int          ret;
+
+       down(&dev->struct_sem);
+       ret = DRM(_histo_info)(buf, start, offset, request, eof, data);
+       up(&dev->struct_sem);
+       return ret;
+}
+#endif
diff --git a/drivers/char/drm/drm_scatter.h b/drivers/char/drm/drm_scatter.h
new file mode 100644 (file)
index 0000000..c1c9f7e
--- /dev/null
@@ -0,0 +1,219 @@
+/* drm_scatter.h -- IOCTLs to manage scatter/gather memory -*- linux-c -*-
+ * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/vmalloc.h>
+#include "drmP.h"
+
+#define DEBUG_SCATTER 0
+
+void DRM(sg_cleanup)( drm_sg_mem_t *entry )
+{
+       struct page *page;
+       int i;
+
+       for ( i = 0 ; i < entry->pages ; i++ ) {
+               page = entry->pagelist[i];
+               if ( page )
+                       ClearPageReserved( page );
+       }
+
+       vfree( entry->virtual );
+
+       DRM(free)( entry->pagelist,
+                 entry->pages * sizeof(*entry->pagelist),
+                 DRM_MEM_PAGES );
+       DRM(free)( entry,
+                 sizeof(*entry),
+                 DRM_MEM_SGLISTS );
+}
+
+int DRM(sg_alloc)( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_scatter_gather_t request;
+       drm_sg_mem_t *entry;
+       unsigned long pages, i, j;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       if ( dev->sg )
+               return -EINVAL;
+
+       if ( copy_from_user( &request,
+                            (drm_scatter_gather_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
+       if ( !entry )
+               return -ENOMEM;
+
+       memset( entry, 0, sizeof(*entry) );
+
+       pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
+       DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
+
+       entry->pages = pages;
+       entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
+                                    DRM_MEM_PAGES );
+       if ( !entry->pagelist ) {
+               DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
+               return -ENOMEM;
+       }
+       memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+       entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
+       if ( !entry->virtual ) {
+               DRM(free)( entry->pagelist,
+                         entry->pages * sizeof(*entry->pagelist),
+                         DRM_MEM_PAGES );
+               DRM(free)( entry,
+                         sizeof(*entry),
+                         DRM_MEM_SGLISTS );
+               return -ENOMEM;
+       }
+
+       /* This also forces the mapping of COW pages, so our page list
+        * will be valid.  Please don't remove it...
+        */
+       memset( entry->virtual, 0, pages << PAGE_SHIFT );
+
+       entry->handle = (unsigned long)entry->virtual;
+
+       DRM_DEBUG( "sg alloc handle  = %08lx\n", entry->handle );
+       DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
+
+       for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
+               pgd = pgd_offset_k( i );
+               if ( !pgd_present( *pgd ) )
+                       goto failed;
+
+               pmd = pmd_offset( pgd, i );
+               if ( !pmd_present( *pmd ) )
+                       goto failed;
+
+               pte = pte_offset( pmd, i );
+               if ( !pte_present( *pte ) )
+                       goto failed;
+
+               entry->pagelist[j] = pte_page( *pte );
+
+               SetPageReserved( entry->pagelist[j] );
+       }
+
+       request.handle = entry->handle;
+
+       if ( copy_to_user( (drm_scatter_gather_t *)arg,
+                          &request,
+                          sizeof(request) ) ) {
+               DRM(sg_cleanup)( entry );
+               return -EFAULT;
+       }
+
+       dev->sg = entry;
+
+#if DEBUG_SCATTER
+       /* Verify that each page points to its virtual address, and vice
+        * versa.
+        */
+       {
+       int error = 0;
+
+       for ( i = 0 ; i < pages ; i++ ) {
+               unsigned long *tmp;
+
+               tmp = (unsigned long *)entry->pagelist[i]->virtual;
+               for ( j = 0 ;
+                     j < PAGE_SIZE / sizeof(unsigned long) ;
+                     j++, tmp++ ) {
+                       *tmp = 0xcafebabe;
+               }
+               tmp = (unsigned long *)((u8 *)entry->virtual +
+                                       (PAGE_SIZE * i));
+               for( j = 0 ;
+                    j < PAGE_SIZE / sizeof(unsigned long) ;
+                    j++, tmp++ ) {
+                       if ( *tmp != 0xcafebabe && error == 0 ) {
+                               error = 1;
+                               DRM_ERROR( "Scatter allocation error, "
+                                          "pagelist does not match "
+                                          "virtual mapping\n" );
+                       }
+               }
+               tmp = (unsigned long *)entry->pagelist[i]->virtual;
+               for(j = 0 ;
+                   j < PAGE_SIZE / sizeof(unsigned long) ;
+                   j++, tmp++) {
+                       *tmp = 0;
+               }
+       }
+       if (error == 0)
+               DRM_ERROR( "Scatter allocation matches pagelist\n" );
+       }
+#endif
+
+       return 0;
+
+ failed:
+       DRM(sg_cleanup)( entry );
+       return -ENOMEM;
+}
+
+int DRM(sg_free)( struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_scatter_gather_t request;
+       drm_sg_mem_t *entry;
+
+       if ( copy_from_user( &request,
+                            (drm_scatter_gather_t *)arg,
+                            sizeof(request) ) )
+               return -EFAULT;
+
+       entry = dev->sg;
+       dev->sg = NULL;
+
+       if ( !entry || entry->handle != request.handle )
+               return -EINVAL;
+
+       DRM_DEBUG( "sg free virtual  = %p\n", entry->virtual );
+
+       DRM(sg_cleanup)( entry );
+
+       return 0;
+}
diff --git a/drivers/char/drm/drm_stub.h b/drivers/char/drm/drm_stub.h
new file mode 100644 (file)
index 0000000..fe8a1bc
--- /dev/null
@@ -0,0 +1,157 @@
+/* drm_stub.h -- -*- linux-c -*-
+ * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
+ *
+ * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#if LINUX_VERSION_CODE < 0x020400
+#include "stubsupport-pre24.h"
+#endif
+
+#define DRM_STUB_MAXCARDS 16   /* Enough for one machine */
+
+static struct drm_stub_list {
+       const char             *name;
+       struct file_operations *fops;
+       struct proc_dir_entry  *dev_root;
+} *DRM(stub_list);
+
+static struct proc_dir_entry *DRM(stub_root);
+
+static struct drm_stub_info {
+       int (*info_register)(const char *name, struct file_operations *fops,
+                            drm_device_t *dev);
+       int (*info_unregister)(int minor);
+} DRM(stub_info);
+
+static int DRM(stub_open)(struct inode *inode, struct file *filp)
+{
+       int                    minor = MINOR(inode->i_rdev);
+       int                    err   = -ENODEV;
+       struct file_operations *old_fops;
+
+       if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
+       old_fops   = filp->f_op;
+       filp->f_op = fops_get(DRM(stub_list)[minor].fops);
+       if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+               fops_put(filp->f_op);
+               filp->f_op = fops_get(old_fops);
+       }
+       fops_put(old_fops);
+
+       return err;
+}
+
+static struct file_operations DRM(stub_fops) = {
+#if LINUX_VERSION_CODE >= 0x020400
+       owner:   THIS_MODULE,
+#endif
+       open:    DRM(stub_open)
+};
+
+static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
+                             drm_device_t *dev)
+{
+       int i;
+
+       if (!DRM(stub_list)) {
+               DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
+                                           * DRM_STUB_MAXCARDS, DRM_MEM_STUB);
+               if(!DRM(stub_list)) return -1;
+               for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
+                       DRM(stub_list)[i].name = NULL;
+                       DRM(stub_list)[i].fops = NULL;
+               }
+       }
+       for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
+               if (!DRM(stub_list)[i].fops) {
+                       DRM(stub_list)[i].name = name;
+                       DRM(stub_list)[i].fops = fops;
+                       DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
+                                                       &DRM(stub_list)[i]
+                                                       .dev_root);
+                       return i;
+               }
+       }
+       return -1;
+}
+
+static int DRM(stub_putminor)(int minor)
+{
+       if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
+       DRM(stub_list)[minor].name = NULL;
+       DRM(stub_list)[minor].fops = NULL;
+       DRM(proc_cleanup)(minor, DRM(stub_root),
+                         DRM(stub_list)[minor].dev_root);
+       if (minor) {
+               inter_module_put("drm");
+       } else {
+               inter_module_unregister("drm");
+               DRM(free)(DRM(stub_list),
+                         sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
+                         DRM_MEM_STUB);
+               unregister_chrdev(DRM_MAJOR, "drm");
+       }
+       return 0;
+}
+
+
+int DRM(stub_register)(const char *name, struct file_operations *fops,
+                      drm_device_t *dev)
+{
+       struct drm_stub_info *i = NULL;
+
+       DRM_DEBUG("\n");
+       if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops)))
+               i = (struct drm_stub_info *)inter_module_get("drm");
+
+       if (i) {
+                               /* Already registered */
+               DRM(stub_info).info_register   = i->info_register;
+               DRM(stub_info).info_unregister = i->info_unregister;
+               DRM_DEBUG("already registered\n");
+       } else if (DRM(stub_info).info_register != DRM(stub_getminor)) {
+               DRM(stub_info).info_register   = DRM(stub_getminor);
+               DRM(stub_info).info_unregister = DRM(stub_putminor);
+               DRM_DEBUG("calling inter_module_register\n");
+               inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
+       }
+       if (DRM(stub_info).info_register)
+               return DRM(stub_info).info_register(name, fops, dev);
+       return -1;
+}
+
+int DRM(stub_unregister)(int minor)
+{
+       DRM_DEBUG("%d\n", minor);
+       if (DRM(stub_info).info_unregister)
+               return DRM(stub_info).info_unregister(minor);
+       return -1;
+}
diff --git a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
new file mode 100644 (file)
index 0000000..d8e77f7
--- /dev/null
@@ -0,0 +1,500 @@
+/* drm_vm.h -- Memory mapping for DRM -*- linux-c -*-
+ * Created: Mon Jan  4 08:58:31 1999 by faith@valinux.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+struct vm_operations_struct   DRM(vm_ops) = {
+       nopage:  DRM(vm_nopage),
+       open:    DRM(vm_open),
+       close:   DRM(vm_close),
+};
+
+struct vm_operations_struct   DRM(vm_shm_ops) = {
+       nopage:  DRM(vm_shm_nopage),
+       open:    DRM(vm_open),
+       close:   DRM(vm_shm_close),
+};
+
+struct vm_operations_struct   DRM(vm_dma_ops) = {
+       nopage:  DRM(vm_dma_nopage),
+       open:    DRM(vm_open),
+       close:   DRM(vm_close),
+};
+
+struct vm_operations_struct   DRM(vm_sg_ops) = {
+       nopage:  DRM(vm_sg_nopage),
+       open:    DRM(vm_open),
+       close:   DRM(vm_close),
+};
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
+                            unsigned long address,
+                            int write_access)
+#else
+                               /* Return type changed in 2.3.23 */
+struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
+                           unsigned long address,
+                           int write_access)
+#endif
+{
+       return NOPAGE_SIGBUS;           /* Disallow mremap */
+}
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                                unsigned long address,
+                                int write_access)
+#else
+                               /* Return type changed in 2.3.23 */
+struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+                               int write_access)
+#endif
+{
+#if LINUX_VERSION_CODE >= 0x020300
+       drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+#else
+       drm_map_t        *map    = (drm_map_t *)vma->vm_pte;
+#endif
+       unsigned long    physical;
+       unsigned long    offset;
+       unsigned long    i;
+       pgd_t            *pgd;
+       pmd_t            *pmd;
+       pte_t            *pte;
+
+       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+       if (!map)                  return NOPAGE_OOM;  /* Nothing allocated */
+
+       offset   = address - vma->vm_start;
+       i = (unsigned long)map->handle + offset;
+       /* We have to walk page tables here because we need large SAREA's, and
+        * they need to be virtually contiguous in kernel space.
+        */
+       pgd = pgd_offset_k( i );
+       if( !pgd_present( *pgd ) ) return NOPAGE_OOM;
+       pmd = pmd_offset( pgd, i );
+       if( !pmd_present( *pmd ) ) return NOPAGE_OOM;
+       pte = pte_offset( pmd, i );
+       if( !pte_present( *pte ) ) return NOPAGE_OOM;
+       physical = (unsigned long)pte_page( *pte )->virtual;
+       atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+
+       DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
+#if LINUX_VERSION_CODE < 0x020317
+       return physical;
+#else
+       return virt_to_page(physical);
+#endif
+}
+
+/* Special close routine which deletes map information if we are the last
+ * person to close a mapping and its not in the global maplist.
+ */
+
+void DRM(vm_shm_close)(struct vm_area_struct *vma)
+{
+       drm_file_t      *priv   = vma->vm_file->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_vma_entry_t *pt, *prev, *next;
+       drm_map_t *map;
+       drm_map_list_t *r_list;
+       struct list_head *list;
+       int found_maps = 0;
+
+       DRM_DEBUG("0x%08lx,0x%08lx\n",
+                 vma->vm_start, vma->vm_end - vma->vm_start);
+#if LINUX_VERSION_CODE < 0x020333
+       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+       atomic_dec(&dev->vma_count);
+
+#if LINUX_VERSION_CODE >= 0x020300
+       map = vma->vm_private_data;
+#else
+       map = vma->vm_pte;
+#endif
+
+       down(&dev->struct_sem);
+       for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
+               next = pt->next;
+#if LINUX_VERSION_CODE >= 0x020300
+               if (pt->vma->vm_private_data == map) found_maps++;
+#else
+               if (pt->vma->vm_pte == map) found_maps++;
+#endif
+               if (pt->vma == vma) {
+                       if (prev) {
+                               prev->next = pt->next;
+                       } else {
+                               dev->vmalist = pt->next;
+                       }
+                       DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
+               } else {
+                       prev = pt;
+               }
+       }
+       /* We were the only map that was found */
+       if(found_maps == 1 &&
+          map->flags & _DRM_REMOVABLE) {
+               /* Check to see if we are in the maplist, if we are not, then
+                * we delete this mappings information.
+                */
+               found_maps = 0;
+               list = &dev->maplist->head;
+               list_for_each(list, &dev->maplist->head) {
+                       r_list = (drm_map_list_t *) list;
+                       if (r_list->map == map) found_maps++;
+               }
+
+               if(!found_maps) {
+                       switch (map->type) {
+                       case _DRM_REGISTERS:
+                       case _DRM_FRAME_BUFFER:
+#if __REALLY_HAVE_MTRR
+                               if (map->mtrr >= 0) {
+                                       int retcode;
+                                       retcode = mtrr_del(map->mtrr,
+                                                          map->offset,
+                                                          map->size);
+                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
+                               }
+#endif
+                               DRM(ioremapfree)(map->handle, map->size);
+                               break;
+                       case _DRM_SHM:
+                               vfree(map->handle);
+                               break;
+                       case _DRM_AGP:
+                       case _DRM_SCATTER_GATHER:
+                               break;
+                       }
+                       DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+               }
+       }
+       up(&dev->struct_sem);
+}
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
+                                unsigned long address,
+                                int write_access)
+#else
+                               /* Return type changed in 2.3.23 */
+struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+                               int write_access)
+#endif
+{
+       drm_file_t       *priv   = vma->vm_file->private_data;
+       drm_device_t     *dev    = priv->dev;
+       drm_device_dma_t *dma    = dev->dma;
+       unsigned long    physical;
+       unsigned long    offset;
+       unsigned long    page;
+
+       if (!dma)                  return NOPAGE_SIGBUS; /* Error */
+       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+       if (!dma->pagelist)        return NOPAGE_OOM ; /* Nothing allocated */
+
+       offset   = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
+       page     = offset >> PAGE_SHIFT;
+       physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
+       atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+
+       DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
+#if LINUX_VERSION_CODE < 0x020317
+       return physical;
+#else
+       return virt_to_page(physical);
+#endif
+}
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+                               int write_access)
+#else
+                               /* Return type changed in 2.3.23 */
+struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
+                              unsigned long address,
+                              int write_access)
+#endif
+{
+#if LINUX_VERSION_CODE >= 0x020300
+       drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
+#else
+       drm_map_t        *map    = (drm_map_t *)vma->vm_pte;
+#endif
+       drm_file_t *priv = vma->vm_file->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_sg_mem_t *entry = dev->sg;
+       unsigned long offset;
+       unsigned long map_offset;
+       unsigned long page_offset;
+       struct page *page;
+
+       if (!entry)                return NOPAGE_SIGBUS; /* Error */
+       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+       if (!entry->pagelist)      return NOPAGE_OOM ;  /* Nothing allocated */
+
+
+       offset = address - vma->vm_start;
+       map_offset = map->offset - dev->sg->handle;
+       page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
+       page = entry->pagelist[page_offset];
+       atomic_inc(&page->count);                       /* Dec. by kernel */
+
+#if LINUX_VERSION_CODE < 0x020317
+       return (unsigned long)virt_to_phys(page->virtual);
+#else
+       return page;
+#endif
+}
+
+void DRM(vm_open)(struct vm_area_struct *vma)
+{
+       drm_file_t      *priv   = vma->vm_file->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_vma_entry_t *vma_entry;
+
+       DRM_DEBUG("0x%08lx,0x%08lx\n",
+                 vma->vm_start, vma->vm_end - vma->vm_start);
+       atomic_inc(&dev->vma_count);
+#if LINUX_VERSION_CODE < 0x020333
+                               /* The map can exist after the fd is closed. */
+       MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+
+       vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
+       if (vma_entry) {
+               down(&dev->struct_sem);
+               vma_entry->vma  = vma;
+               vma_entry->next = dev->vmalist;
+               vma_entry->pid  = current->pid;
+               dev->vmalist    = vma_entry;
+               up(&dev->struct_sem);
+       }
+}
+
+void DRM(vm_close)(struct vm_area_struct *vma)
+{
+       drm_file_t      *priv   = vma->vm_file->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_vma_entry_t *pt, *prev;
+
+       DRM_DEBUG("0x%08lx,0x%08lx\n",
+                 vma->vm_start, vma->vm_end - vma->vm_start);
+#if LINUX_VERSION_CODE < 0x020333
+       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+       atomic_dec(&dev->vma_count);
+
+       down(&dev->struct_sem);
+       for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+               if (pt->vma == vma) {
+                       if (prev) {
+                               prev->next = pt->next;
+                       } else {
+                               dev->vmalist = pt->next;
+                       }
+                       DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
+                       break;
+               }
+       }
+       up(&dev->struct_sem);
+}
+
+int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
+{
+       drm_file_t       *priv   = filp->private_data;
+       drm_device_t     *dev;
+       drm_device_dma_t *dma;
+       unsigned long    length  = vma->vm_end - vma->vm_start;
+
+       lock_kernel();
+       dev      = priv->dev;
+       dma      = dev->dma;
+       DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+                 vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+                               /* Length must match exact page count */
+       if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
+               unlock_kernel();
+               return -EINVAL;
+       }
+       unlock_kernel();
+
+       vma->vm_ops   = &DRM(vm_dma_ops);
+       vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+
+#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
+                               /* In Linux 2.2.3 and above, this is
+                                  handled in do_mmap() in mm/mmap.c. */
+       ++filp->f_count;
+#endif
+       vma->vm_file  =  filp;  /* Needed for drm_vm_open() */
+       DRM(vm_open)(vma);
+       return 0;
+}
+
+#ifndef DRIVER_GET_MAP_OFS
+#define DRIVER_GET_MAP_OFS()   (map->offset)
+#endif
+
+#ifndef DRIVER_GET_REG_OFS
+#ifdef __alpha__
+#define DRIVER_GET_REG_OFS()   (dev->hose->dense_mem_base -    \
+                                dev->hose->mem_space->start)
+#else
+#define DRIVER_GET_REG_OFS()   0
+#endif
+#endif
+
+int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
+{
+       drm_file_t      *priv   = filp->private_data;
+       drm_device_t    *dev    = priv->dev;
+       drm_map_t       *map    = NULL;
+       drm_map_list_t  *r_list;
+       unsigned long   offset  = 0;
+       struct list_head *list;
+
+       DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+                 vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+
+       if ( !priv->authenticated ) return -EACCES;
+
+       if (!VM_OFFSET(vma)) return DRM(mmap_dma)(filp, vma);
+
+                               /* A sequential search of a linked list is
+                                  fine here because: 1) there will only be
+                                  about 5-10 entries in the list and, 2) a
+                                  DRI client only has to do this mapping
+                                  once, so it doesn't have to be optimized
+                                  for performance, even if the list was a
+                                  bit longer. */
+       list_for_each(list, &dev->maplist->head) {
+               unsigned long off;
+
+               r_list = (drm_map_list_t *)list;
+               map = r_list->map;
+               if (!map) continue;
+               off = DRIVER_GET_MAP_OFS();
+               if (off == VM_OFFSET(vma)) break;
+       }
+
+       if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+               return -EPERM;
+
+                               /* Check for valid size. */
+       if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+
+       if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
+               vma->vm_flags &= VM_MAYWRITE;
+#if defined(__i386__)
+               pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+                               /* Ye gads this is ugly.  With more thought
+                                   we could move this up higher and use
+                                   `protection_map' instead.  */
+               vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+                       __pte(pgprot_val(vma->vm_page_prot)))));
+#endif
+       }
+
+       switch (map->type) {
+       case _DRM_FRAME_BUFFER:
+       case _DRM_REGISTERS:
+       case _DRM_AGP:
+               if (VM_OFFSET(vma) >= __pa(high_memory)) {
+#if defined(__i386__)
+                       if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+                               pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+                               pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+                       }
+#elif defined(__ia64__)
+                       if (map->type != _DRM_AGP)
+                               vma->vm_page_prot =
+                                       pgprot_writecombine(vma->vm_page_prot);
+#elif defined(__powerpc__)
+                       pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+#endif
+                       vma->vm_flags |= VM_IO; /* not in core dump */
+               }
+               offset = DRIVER_GET_REG_OFS();
+               if (remap_page_range(vma->vm_start,
+                                    VM_OFFSET(vma) + offset,
+                                    vma->vm_end - vma->vm_start,
+                                    vma->vm_page_prot))
+                               return -EAGAIN;
+               DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
+                         " offset = 0x%lx\n",
+                         map->type,
+                         vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
+               vma->vm_ops = &DRM(vm_ops);
+               break;
+       case _DRM_SHM:
+               vma->vm_ops = &DRM(vm_shm_ops);
+#if LINUX_VERSION_CODE >= 0x020300
+               vma->vm_private_data = (void *)map;
+#else
+               vma->vm_pte = (unsigned long)map;
+#endif
+                               /* Don't let this area swap.  Change when
+                                  DRM_KERNEL advisory is supported. */
+               vma->vm_flags |= VM_LOCKED;
+               break;
+       case _DRM_SCATTER_GATHER:
+               vma->vm_ops = &DRM(vm_sg_ops);
+#if LINUX_VERSION_CODE >= 0x020300
+               vma->vm_private_data = (void *)map;
+#else
+               vma->vm_pte = (unsigned long)map;
+#endif
+                vma->vm_flags |= VM_LOCKED;
+                break;
+       default:
+               return -EINVAL; /* This should never happen. */
+       }
+       vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+
+#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
+                               /* In Linux 2.2.3 and above, this is
+                                  handled in do_mmap() in mm/mmap.c. */
+       ++filp->f_count;
+#endif
+       vma->vm_file  =  filp;  /* Needed for drm_vm_open() */
+       DRM(vm_open)(vma);
+       return 0;
+}
diff --git a/drivers/char/drm/ffb.h b/drivers/char/drm/ffb.h
new file mode 100644 (file)
index 0000000..01a676a
--- /dev/null
@@ -0,0 +1,15 @@
+/* ffb.h -- ffb DRM template customization -*- linux-c -*-
+ */
+
+#ifndef __FFB_H__
+#define __FFB_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) ffb_##x
+
+/* General customization:
+ */
+#define __HAVE_KERNEL_CTX_SWITCH       1
+#define __HAVE_RELEASE                 1
+#endif
index 4e8b29b73044df260a80577d9b270609c77b9bc9..0eb4abb9fab697eabef6272c24cdb321c9eabf29 100644 (file)
 #include <linux/sched.h>
 #include <asm/upa.h>
 
+#include "ffb.h"
 #include "drmP.h"
 
 #include "ffb_drv.h"
 
-static int ffb_alloc_queue(drm_device_t *dev, int is_2d_only)
+static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
 {
-       ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) (dev + 1);
+       ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
        int i;
 
        for (i = 0; i < FFB_MAX_CTXS; i++) {
@@ -353,9 +354,9 @@ static void FFBWait(ffb_fbcPtr ffb)
        } while (--limit);
 }
 
-int ffb_context_switch(drm_device_t *dev, int old, int new)
+int DRM(context_switch)(drm_device_t *dev, int old, int new)
 {
-       ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) (dev + 1);
+       ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
 
         atomic_inc(&dev->total_ctx);
 
@@ -381,8 +382,8 @@ int ffb_context_switch(drm_device_t *dev, int old, int new)
         return 0;
 }
 
-int ffb_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(resctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
 {
        drm_ctx_res_t   res;
        drm_ctx_t       ctx;
@@ -408,8 +409,8 @@ int ffb_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
 }
 
 
-int ffb_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(addctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev    = priv->dev;
@@ -418,7 +419,7 @@ int ffb_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
                return -EFAULT;
-       idx = ffb_alloc_queue(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
+       idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
        if (idx < 0)
                return -ENFILE;
 
@@ -429,12 +430,12 @@ int ffb_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int ffb_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(modctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev    = priv->dev;
-       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) (dev + 1);
+       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) dev->dev_private;
        struct ffb_hw_context *hwctx;
        drm_ctx_t ctx;
        int idx;
@@ -458,12 +459,12 @@ int ffb_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int ffb_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(getctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev    = priv->dev;
-       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) (dev + 1);
+       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) dev->dev_private;
        struct ffb_hw_context *hwctx;
        drm_ctx_t ctx;
        int idx;
@@ -490,8 +491,8 @@ int ffb_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int ffb_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
+int DRM(switchctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+                  unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev    = priv->dev;
@@ -500,11 +501,11 @@ int ffb_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
                return -EFAULT;
        DRM_DEBUG("%d\n", ctx.handle);
-       return ffb_context_switch(dev, dev->last_context, ctx.handle);
+       return DRM(context_switch)(dev, dev->last_context, ctx.handle);
 }
 
-int ffb_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(newctx)(struct inode *inode, struct file *filp, unsigned int cmd,
+               unsigned long arg)
 {
        drm_ctx_t       ctx;
 
@@ -515,13 +516,13 @@ int ffb_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int ffb_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int DRM(rmctx)(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_ctx_t       ctx;
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev    = priv->dev;
-       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) (dev + 1);
+       ffb_dev_priv_t  *fpriv  = (ffb_dev_priv_t *) dev->dev_private;
        int idx;
 
        if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
index a250500adc065d7942fdca328212980c482279ef..a8c8f9ecda77b0dcbefbb00f46d3bde62bc97eb5 100644 (file)
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  */
 
+#include <linux/config.h>
+#include "ffb.h"
 #include "drmP.h"
 
+#include "ffb_drv.h"
+
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <asm/shmparam.h>
 #include <asm/oplib.h>
 #include <asm/upa.h>
 
-#include "ffb_drv.h"
-
-#define FFB_NAME       "ffb"
-#define FFB_DESC       "Creator/Creator3D"
-#define FFB_DATE       "20000517"
-#define FFB_MAJOR      0
-#define FFB_MINOR      0
-#define FFB_PATCHLEVEL 1
-
-/* Forward declarations. */
-int  ffb_init(void);
-void ffb_cleanup(void);
-static int  ffb_version(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-static int  ffb_open(struct inode *inode, struct file *filp);
-static int  ffb_release(struct inode *inode, struct file *filp);
-static int  ffb_ioctl(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-static int  ffb_lock(struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg);
-static int  ffb_unlock(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-static int ffb_mmap(struct file *filp, struct vm_area_struct *vma);
-static unsigned long ffb_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
-
-/* From ffb_context.c */
-extern int ffb_resctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_addctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_modctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_getctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_switchctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_newctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_rmctx(struct inode *, struct file *, unsigned int, unsigned long);
-extern int ffb_context_switch(drm_device_t *, int, int);
-
-static struct file_operations ffb_fops = {
-       owner:                  THIS_MODULE,
-       open:                   ffb_open,
-       flush:                  drm_flush,
-       release:                ffb_release,
-       ioctl:                  ffb_ioctl,
-       mmap:                   ffb_mmap,
-       read:                   drm_read,
-       fasync:                 drm_fasync,
-       poll:                   drm_poll,
-       get_unmapped_area:      ffb_get_unmapped_area,
-};
-
-/* This is just a template, we make a new copy for each FFB
- * we discover at init time so that each one gets a unique
- * misc device minor number.
- */
-static struct miscdevice ffb_misc = {
-       minor:  MISC_DYNAMIC_MINOR,
-       name:   FFB_NAME,
-       fops:   &ffb_fops,
-};
-
-static drm_ioctl_desc_t ffb_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]    = { ffb_version,     0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]  = { drm_getmagic,    0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]  = { drm_irq_busid,   0, 1 }, /* XXX */
-
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]      = { drm_block,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]    = { drm_unblock,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]    = { drm_addmap,      1, 1 },
-       
-       /* The implementation is currently a nop just like on tdfx.
-        * Later we can do something more clever. -DaveM
-        */
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]    = { ffb_addctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]     = { ffb_rmctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]    = { ffb_modctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]    = { ffb_getctx,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { ffb_switchctx,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]    = { ffb_newctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]    = { ffb_resctx,      1, 0 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]   = { drm_adddraw,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]    = { drm_rmdraw,      1, 1 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]       = { ffb_lock,        1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]     = { ffb_unlock,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]     = { drm_finish,      1, 0 },
-};
-#define FFB_IOCTL_COUNT DRM_ARRAY_SIZE(ffb_ioctls)
-
-#ifdef MODULE
-static char *ffb = NULL;
-#endif
-
-MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
-MODULE_DESCRIPTION("Sun Creator/Creator3D DRI");
-
-static int ffb_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-       
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-       
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-
-       /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-       
-       /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-       
-       /* Clear map area information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-
-                       default:
-                               break;
-                       };
-
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-       
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-       
-       return 0;
+#define DRIVER_AUTHOR          "David S. Miller"
+
+#define DRIVER_NAME            "ffb"
+#define DRIVER_DESC            "Creator/Creator3D"
+#define DRIVER_DATE            "20000517"
+
+#define DRIVER_MAJOR           0
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      1
+
+#define DRIVER_FOPS                                            \
+static struct file_operations  DRM(fops) = {                   \
+       owner:                  THIS_MODULE,                    \
+       open:                   DRM(open),                      \
+       flush:                  DRM(flush),                     \
+       release:                DRM(release),                   \
+       ioctl:                  DRM(ioctl),                     \
+       mmap:                   DRM(mmap),                      \
+       read:                   DRM(read),                      \
+       fasync:                 DRM(fasync),                    \
+       poll:                   DRM(poll),                      \
+       get_unmapped_area:      ffb_get_unmapped_area,          \
 }
 
-drm_device_t **ffb_dev_table;
-static int ffb_dev_table_size;
+#define DRIVER_COUNT_CARDS()   ffb_count_card_instances()
+/* Allocate private structure and fill it */
+#define DRIVER_PRESETUP()      do {            \
+       int _ret;                               \
+       _ret = ffb_presetup(dev);               \
+       if(_ret != 0) return _ret;              \
+} while(0)
+
+/* Free private structure */
+#define DRIVER_PRETAKEDOWN()   do {                            \
+       if(dev->dev_private) kfree(dev->dev_private);           \
+} while(0)
+
+#define DRIVER_POSTCLEANUP()   do {                            \
+       if(ffb_position != NULL) kfree(ffb_position);           \
+} while(0)
+
+/* We have to free up the rogue hw context state holding error or 
+ * else we will leak it.
+ */
+#define DRIVER_RELEASE()       do {                                    \
+       ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;    \
+       int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);    \
+       int idx;                                                        \
+                                                                       \
+       idx = context - 1;                                              \
+       if (fpriv && fpriv->hw_state[idx] != NULL) {                    \
+               kfree(fpriv->hw_state[idx]);                            \
+               fpriv->hw_state[idx] = NULL;                            \
+       }                                                               \
+} while(0)
+
+/* For mmap customization */
+#define DRIVER_GET_MAP_OFS     (map->offset & 0xffffffff)
+#define DRIVER_GET_REG_OFS()   ffb_get_reg_offset(dev)
+
+typedef struct _ffb_position_t {
+       int node;
+       int root;
+} ffb_position_t;
+
+static ffb_position_t *ffb_position;
 
 static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
 {
@@ -247,7 +136,8 @@ static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
        };
 }
 
-static void __init ffb_apply_upa_parent_ranges(int parent, struct linux_prom64_registers *regs)
+static void ffb_apply_upa_parent_ranges(int parent, 
+                                       struct linux_prom64_registers *regs)
 {
        struct linux_prom64_ranges ranges[PROMREG_MAX];
        char name[128];
@@ -277,26 +167,16 @@ static void __init ffb_apply_upa_parent_ranges(int parent, struct linux_prom64_r
        return;
 }
 
-static int __init ffb_init_one(int prom_node, int parent_node, int instance)
+static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
+                       int instance)
 {
        struct linux_prom64_registers regs[2*PROMREG_MAX];
-       drm_device_t *dev;
-       ffb_dev_priv_t *ffb_priv;
-       int ret, i;
-
-       dev = kmalloc(sizeof(drm_device_t) + sizeof(ffb_dev_priv_t), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
-
-       memset(dev, 0, sizeof(*dev));
-       spin_lock_init(&dev->count_lock);
-       sema_init(&dev->struct_sem, 1);
+       ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
+       int i;
 
-       ffb_priv = (ffb_dev_priv_t *) (dev + 1);
        ffb_priv->prom_node = prom_node;
        if (prom_getproperty(ffb_priv->prom_node, "reg",
                             (void *)regs, sizeof(regs)) <= 0) {
-               kfree(dev);
                return -EINVAL;
        }
        ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
@@ -306,37 +186,39 @@ static int __init ffb_init_one(int prom_node, int parent_node, int instance)
        get_ffb_type(ffb_priv, instance);
        for (i = 0; i < FFB_MAX_CTXS; i++)
                ffb_priv->hw_state[i] = NULL;
+       
+       return 0;
+}
 
-       ffb_dev_table[instance] = dev;
+static int ffb_presetup(drm_device_t *dev)
+{
+       ffb_dev_priv_t  *ffb_priv;
+       drm_device_t *temp_dev;
+       int ret = 0;
+       int i;
 
-#ifdef MODULE
-       drm_parse_options(ffb);
-#endif
+       /* Check for the case where no device was found. */
+       if(ffb_position == NULL) return -ENODEV;
 
-       memcpy(&ffb_priv->miscdev, &ffb_misc, sizeof(ffb_misc));
-       ret = misc_register(&ffb_priv->miscdev);
-       if (ret) {
-               ffb_dev_table[instance] = NULL;
-               kfree(dev);
-               return ret;
+       /* Find our instance number by finding our device in dev structure */
+       for(i = 0; i < DRM(numdevs); i++) {
+               temp_dev = &(DRM(device)[i]);
+               if(temp_dev == dev) break;
+       }
+       if(i == DRM(numdevs)) {
+               return -ENODEV;
        }
 
-       dev->device = MKDEV(MISC_MAJOR, ffb_priv->miscdev.minor);
-       dev->name = FFB_NAME;
-
-       drm_mem_init();
-       drm_proc_init(dev);
+       ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
+       if(!ffb_priv) return -ENOMEM;
+       memset(ffb_priv, 0, sizeof(*ffb_priv));
+       dev->dev_private = ffb_priv;
 
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d at %016lx\n",
-                FFB_NAME,
-                FFB_MAJOR,
-                FFB_MINOR,
-                FFB_PATCHLEVEL,
-                FFB_DATE,
-                ffb_priv->miscdev.minor,
-                ffb_priv->card_phys_base);
-       
-       return 0;
+       ret = ffb_init_one(dev,
+                          ffb_position[i].node,
+                          ffb_position[i].root,
+                          i);
+       return ret;
 }
 
 static int __init ffb_count_siblings(int root)
@@ -351,28 +233,6 @@ static int __init ffb_count_siblings(int root)
        return count;
 }
 
-static int __init ffb_init_dev_table(void)
-{
-       int root, total;
-
-       total = ffb_count_siblings(prom_root_node);
-       root = prom_getchild(prom_root_node);
-       for (root = prom_searchsiblings(root, "upa"); root;
-            root = prom_searchsiblings(prom_getsibling(root), "upa"))
-               total += ffb_count_siblings(root);
-
-       if (!total)
-               return -ENODEV;
-
-       ffb_dev_table = kmalloc(sizeof(drm_device_t *) * total, GFP_KERNEL);
-       if (!ffb_dev_table)
-               return -ENOMEM;
-
-       ffb_dev_table_size = total;
-
-       return 0;
-}
-
 static int __init ffb_scan_siblings(int root, int instance)
 {
        int node, child;
@@ -380,534 +240,70 @@ static int __init ffb_scan_siblings(int root, int instance)
        child = prom_getchild(root);
        for (node = prom_searchsiblings(child, "SUNW,ffb"); node;
             node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) {
-               ffb_init_one(node, root, instance);
+               ffb_position[instance].node = node;
+               ffb_position[instance].root = root;
                instance++;
        }
 
        return instance;
 }
 
-int __init ffb_init(void)
+static int __init ffb_count_card_instances(void)
 {
-       int root, instance, ret;
-
-       ret = ffb_init_dev_table();
-       if (ret)
-               return ret;
-
-       instance = ffb_scan_siblings(prom_root_node, 0);
+       int root, total, instance;
 
+       total = ffb_count_siblings(prom_root_node);
        root = prom_getchild(prom_root_node);
        for (root = prom_searchsiblings(root, "upa"); root;
             root = prom_searchsiblings(prom_getsibling(root), "upa"))
-               instance = ffb_scan_siblings(root, instance);
-
-       return 0;
-}
-
-void __exit ffb_cleanup(void)
-{
-       int instance;
-
-       DRM_DEBUG("\n");
-       
-       drm_proc_cleanup();
-       for (instance = 0; instance < ffb_dev_table_size; instance++) {
-               drm_device_t *dev = ffb_dev_table[instance];
-               ffb_dev_priv_t *ffb_priv;
-
-               if (!dev)
-                       continue;
-
-               ffb_priv = (ffb_dev_priv_t *) (dev + 1);
-               if (misc_deregister(&ffb_priv->miscdev)) {
-                       DRM_ERROR("Cannot unload module\n");
-               } else {
-                       DRM_INFO("Module unloaded\n");
-               }
-               ffb_takedown(dev);
-               kfree(dev);
-               ffb_dev_table[instance] = NULL;
-       }
-       kfree(ffb_dev_table);
-       ffb_dev_table = NULL;
-       ffb_dev_table_size = 0;
-}
-
-static int ffb_version(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       drm_version_t version;
-       int len, ret;
-
-       ret = copy_from_user(&version, (drm_version_t *)arg, sizeof(version));
-       if (ret)
-               return -EFAULT;
-
-       version.version_major           = FFB_MAJOR;
-       version.version_minor           = FFB_MINOR;
-       version.version_patchlevel      = FFB_PATCHLEVEL;
-
-       len = strlen(FFB_NAME);
-       if (len > version.name_len)
-               len = version.name_len;
-       version.name_len = len;
-       if (len && version.name) {
-               ret = copy_to_user(version.name, FFB_NAME, len);
-               if (ret)
-                       return -EFAULT;
-       }
-
-       len = strlen(FFB_DATE);
-       if (len > version.date_len)
-               len = version.date_len;
-       version.date_len = len;
-       if (len && version.date) {
-               ret = copy_to_user(version.date, FFB_DATE, len);
-               if (ret)
-                       return -EFAULT;
-       }
-
-       len = strlen(FFB_DESC);
-       if (len > version.desc_len)
-               len = version.desc_len;
-       version.desc_len = len;
-       if (len && version.desc) {
-               ret = copy_to_user(version.desc, FFB_DESC, len);
-               if (ret)
-                       return -EFAULT;
-       }
-
-       ret = copy_to_user((drm_version_t *) arg, &version, sizeof(version));
-       if (ret)
-               ret = -EFAULT;
-
-       return ret;
-}
-
-static int ffb_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma            = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-       
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       return 0;
-}
-
-static int ffb_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t *dev;
-       int minor, i;
-       int ret = 0;
-
-       minor = MINOR(inode->i_rdev);
-       for (i = 0; i < ffb_dev_table_size; i++) {
-               ffb_dev_priv_t *ffb_priv;
-
-               ffb_priv = (ffb_dev_priv_t *) (ffb_dev_table[i] + 1);
-
-               if (ffb_priv->miscdev.minor == minor)
-                       break;
-       }
-
-       if (i >= ffb_dev_table_size)
-               return -EINVAL;
-
-       dev = ffb_dev_table[i];
-       if (!dev)
-               return -EINVAL;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       ret = drm_open_helper(inode, filp, dev);
-       if (!ret) {
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return ffb_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       return ret;
-}
-
-static int ffb_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev;
-       int ret = 0;
-
-       lock_kernel();
-       dev = priv->dev;
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (dev->lock.hw_lock != NULL
-           && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
-           && dev->lock.pid == current->pid) {
-               ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) (dev + 1);
-               int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
-               int idx;
-
-               /* We have to free up the rogue hw context state
-                * holding error or else we will leak it.
-                */
-               idx = context - 1;
-               if (fpriv->hw_state[idx] != NULL) {
-                       kfree(fpriv->hw_state[idx]);
-                       fpriv->hw_state[idx] = NULL;
-               }
-       }
-
-       ret = drm_release(inode, filp);
-
-       if (!ret) {
-               atomic_inc(&dev->total_close);
-               spin_lock(&dev->count_lock);
-               if (!--dev->open_count) {
-                       if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                               DRM_ERROR("Device busy: %d %d\n",
-                                         atomic_read(&dev->ioctl_count),
-                                         dev->blocked);
-                               spin_unlock(&dev->count_lock);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       spin_unlock(&dev->count_lock);
-                       ret = ffb_takedown(dev);
-                       unlock_kernel();
-                       return ret;
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return ret;
-}
-
-static int ffb_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-       int              ret;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-       
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= FFB_IOCTL_COUNT) {
-               ret = -EINVAL;
-       } else {
-               ioctl     = &ffb_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       ret = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       ret = -EACCES;
-               } else {
-                       ret = (func)(inode, filp, cmd, arg);
-               }
-       }
-       
-       atomic_dec(&dev->ioctl_count);
-
-       return ret;
-}
-
-static int ffb_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
-        drm_file_t        *priv        = filp->private_data;
-        drm_device_t      *dev = priv->dev;
-        DECLARE_WAITQUEUE(entry, current);
-        int               ret  = 0;
-        drm_lock_t        lock;
-
-       ret = copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock));
-       if (ret)
-               return -EFAULT;
-
-        if (lock.context == DRM_KERNEL_CONTEXT) {
-                DRM_ERROR("Process %d using kernel context %d\n",
-                          current->pid, lock.context);
-                return -EINVAL;
-        }
-
-        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                  lock.context, current->pid, dev->lock.hw_lock->lock,
-                  lock.flags);
-
-       add_wait_queue(&dev->lock.lock_queue, &entry);
-       for (;;) {
-               if (!dev->lock.hw_lock) {
-                       /* Device has been unregistered */
-                       ret = -EINTR;
-                       break;
-               }
-               if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                 lock.context)) {
-                       dev->lock.pid       = current->pid;
-                       dev->lock.lock_time = jiffies;
-                       atomic_inc(&dev->total_locks);
-                       break;  /* Got lock */
-               }
-                        
-               /* Contention */
-               atomic_inc(&dev->total_sleeps);
-               current->state = TASK_INTERRUPTIBLE;
-               current->policy |= SCHED_YIELD;
-               schedule();
-               if (signal_pending(current)) {
-                       ret = -ERESTARTSYS;
-                       break;
-               }
-       }
-       current->state = TASK_RUNNING;
-       remove_wait_queue(&dev->lock.lock_queue, &entry);
-
-        if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
-               if (dev->last_context != lock.context)
-                       ffb_context_switch(dev, dev->last_context, lock.context);
-       }
-
-        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-        return ret;
-}
-
-int ffb_unlock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-       unsigned int old, new, prev, ctx;
-       int ret;
-
-       ret = copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock));
-       if (ret)
-               return -EFAULT;
-       
-       if ((ctx = lock.context) == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-
-       /* We no longer really hold it, but if we are the next
-        * agent to request it then we should just be able to
-        * take it immediately and not eat the ioctl.
-        */
-       dev->lock.pid = 0;
-       {
-               __volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
-
-               do {
-                       old  = *plock;
-                       new  = ctx;
-                       prev = cmpxchg(plock, old, new);
-               } while (prev != old);
-       }
-
-       wake_up_interruptible(&dev->lock.lock_queue);
-       
-       unblock_all_signals();
-       return 0;
-}
-
-extern struct vm_operations_struct drm_vm_ops;
-extern struct vm_operations_struct drm_vm_shm_ops;
-extern struct vm_operations_struct drm_vm_shm_lock_ops;
-
-static int ffb_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_map_t       *map    = NULL;
-       ffb_dev_priv_t  *ffb_priv;
-       int             i, minor;
-       
-       DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-                 vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-       minor = MINOR(filp->f_dentry->d_inode->i_rdev);
-       ffb_priv = NULL;
-       for (i = 0; i < ffb_dev_table_size; i++) {
-               ffb_priv = (ffb_dev_priv_t *) (ffb_dev_table[i] + 1);
-               if (ffb_priv->miscdev.minor == minor)
-                       break;
-       }
-       if (i >= ffb_dev_table_size)
-               return -EINVAL;
-
-       /* We don't support/need dma mappings, so... */
-       if (!VM_OFFSET(vma))
-               return -EINVAL;
-
-       for (i = 0; i < dev->map_count; i++) {
-               unsigned long off;
-
-               map = dev->maplist[i];
-
-               /* Ok, a little hack to make 32-bit apps work. */
-               off = (map->offset & 0xffffffff);
-               if (off == VM_OFFSET(vma))
-                       break;
-       }
-
-       if (i >= dev->map_count)
-               return -EINVAL;
-
-       if (!map ||
-           ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
-               return -EPERM;
+               total += ffb_count_siblings(root);
 
-       if (map->size != (vma->vm_end - vma->vm_start))
-               return -EINVAL;
+       ffb_position = kmalloc(sizeof(ffb_position_t) * total, GFP_KERNEL);
 
-       /* Set read-only attribute before mappings are created
-        * so it works for fb/reg maps too.
+       /* Actual failure will be caught during ffb_presetup b/c we can't catch
+        * it easily here.
         */
-       if (map->flags & _DRM_READ_ONLY)
-               vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
-                       __pte(pgprot_val(vma->vm_page_prot)))));
-
-       switch (map->type) {
-       case _DRM_FRAME_BUFFER:
-               /* FALLTHROUGH */
-
-       case _DRM_REGISTERS:
-               /* In order to handle 32-bit drm apps/xserver we
-                * play a trick.  The mappings only really specify
-                * the 32-bit offset from the cards 64-bit base
-                * address, and we just add in the base here.
-                */
-               vma->vm_flags |= VM_IO;
-               if (io_remap_page_range(vma->vm_start,
-                                       ffb_priv->card_phys_base + VM_OFFSET(vma),
-                                       vma->vm_end - vma->vm_start,
-                                       vma->vm_page_prot, 0))
-                       return -EAGAIN;
-
-               vma->vm_ops = &drm_vm_ops;
-               break;
-       case _DRM_SHM:
-               if (map->flags & _DRM_CONTAINS_LOCK)
-                       vma->vm_ops = &drm_vm_shm_lock_ops;
-               else {
-                       vma->vm_ops = &drm_vm_shm_ops;
-                       vma->vm_private_data = (void *) map;
-               }
+       if(!ffb_position) return -ENOMEM;
 
-               /* Don't let this area swap.  Change when
-                * DRM_KERNEL advisory is supported.
-                */
-               vma->vm_flags |= VM_LOCKED;
-               break;
-       default:
-               return -EINVAL; /* This should never happen. */
-       };
+       instance = ffb_scan_siblings(prom_root_node, 0);
 
-       vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+       root = prom_getchild(prom_root_node);
+       for (root = prom_searchsiblings(root, "upa"); root;
+            root = prom_searchsiblings(prom_getsibling(root), "upa"))
+               instance = ffb_scan_siblings(root, instance);
 
-       vma->vm_file = filp; /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
-       return 0;
+       return total;
 }
 
 static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
 {
        drm_file_t      *priv   = filp->private_data;
        drm_device_t    *dev;
+       drm_map_list_t  *r_list;
+       struct list_head *list;
        drm_map_t       *map;
-       int             i;
 
        if (!priv || (dev = priv->dev) == NULL)
                return NULL;
 
-       for (i = 0; i < dev->map_count; i++) {
+       list_for_each(list, &dev->maplist->head) {
                unsigned long uoff;
 
-               map = dev->maplist[i];
-
-               /* Ok, a little hack to make 32-bit apps work. */
+               r_list = (drm_map_list_t *)list;
+               map = r_list->map;
+               if (!map) continue;
                uoff = (map->offset & 0xffffffff);
-               if (uoff == off)
-                       return map;
+               if (uoff == off) return map;
        }
+
        return NULL;
 }
 
-static unsigned long ffb_get_unmapped_area(struct file *filp, unsigned long hint, unsigned long len, unsigned long pgoff, unsigned long flags)
+static unsigned long ffb_get_unmapped_area(struct file *filp,
+                                          unsigned long hint,
+                                          unsigned long len,
+                                          unsigned long pgoff,
+                                          unsigned long flags)
 {
        drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
        unsigned long addr = -ENOMEM;
@@ -947,5 +343,46 @@ static unsigned long ffb_get_unmapped_area(struct file *filp, unsigned long hint
        return addr;
 }
 
-module_init(ffb_init);
-module_exit(ffb_cleanup);
+static unsigned long ffb_get_reg_offset(drm_device_t *dev)
+{
+       ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
+
+       if(ffb_priv) {
+               return ffb_priv->card_phys_base;
+       }
+       return 0;
+}
+
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
+
+#ifndef MODULE
+/* DRM(options) is called by the kernel to parse command-line options
+ * passed via the boot-loader (e.g., LILO).  It calls the insmod option
+ * routine, drm_parse_drm.
+ */
+
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init ffb_options( char *str )
+{
+       DRM(parse_options)( str );
+       return 1;
+}
+
+__setup( DRIVER_NAME "=", ffb_options );
+#endif
+
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
diff --git a/drivers/char/drm/fops.c b/drivers/char/drm/fops.c
deleted file mode 100644 (file)
index 58b1a80..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/* fops.c -- File operations for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *    Daryll Strauss <daryll@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include <linux/poll.h>
-
-/* drm_open is called whenever a process opens /dev/drm. */
-
-int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
-{
-       kdev_t       minor = MINOR(inode->i_rdev);
-       drm_file_t   *priv;
-
-       if (filp->f_flags & O_EXCL)   return -EBUSY; /* No exclusive opens */
-       if (!drm_cpu_valid())         return -EINVAL;
-
-       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
-
-       priv                = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
-       if(priv == NULL)
-               return -ENOMEM;
-       memset(priv, 0, sizeof(*priv));
-
-       filp->private_data  = priv;
-       priv->uid           = current->euid;
-       priv->pid           = current->pid;
-       priv->minor         = minor;
-       priv->dev           = dev;
-       priv->ioctl_count   = 0;
-       priv->authenticated = capable(CAP_SYS_ADMIN);
-
-       down(&dev->struct_sem);
-       if (!dev->file_last) {
-               priv->next      = NULL;
-               priv->prev      = NULL;
-               dev->file_first = priv;
-               dev->file_last  = priv;
-       } else {
-               priv->next           = NULL;
-               priv->prev           = dev->file_last;
-               dev->file_last->next = priv;
-               dev->file_last       = priv;
-       }
-       up(&dev->struct_sem);
-       
-       return 0;
-}
-
-int drm_flush(struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev    = priv->dev;
-
-       DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
-                 current->pid, dev->device, dev->open_count);
-       return 0;
-}
-
-/* drm_release is called whenever a process closes /dev/drm*.  Linux calls
-   this only if any mappings have been closed. */
-
-int drm_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev    = priv->dev;
-
-       DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
-                 current->pid, dev->device, dev->open_count);
-
-       if (dev->lock.hw_lock
-           && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
-           && dev->lock.pid == current->pid) {
-               DRM_ERROR("Process %d dead, freeing lock for context %d\n",
-                         current->pid,
-                         _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-               drm_lock_free(dev,
-                             &dev->lock.hw_lock->lock,
-                             _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-               
-                               /* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
-       }
-       drm_reclaim_buffers(dev, priv->pid);
-
-       drm_fasync(-1, filp, 0);
-
-       down(&dev->struct_sem);
-       if (priv->prev) priv->prev->next = priv->next;
-       else            dev->file_first  = priv->next;
-       if (priv->next) priv->next->prev = priv->prev;
-       else            dev->file_last   = priv->prev;
-       up(&dev->struct_sem);
-       
-       drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-       
-       return 0;
-}
-
-int drm_fasync(int fd, struct file *filp, int on)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev    = priv->dev;
-       int           retcode;
-       
-       DRM_DEBUG("fd = %d, device = 0x%x\n", fd, dev->device);
-       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-       if (retcode < 0) return retcode;
-       return 0;
-}
-
-
-/* The drm_read and drm_write_string code (especially that which manages
-   the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
-   DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
-
-ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev    = priv->dev;
-       int           left;
-       int           avail;
-       int           send;
-       int           cur;
-
-       DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
-       
-       while (dev->buf_rp == dev->buf_wp) {
-               DRM_DEBUG("  sleeping\n");
-               if (filp->f_flags & O_NONBLOCK) {
-                       return -EAGAIN;
-               }
-               interruptible_sleep_on(&dev->buf_readers);
-               if (signal_pending(current)) {
-                       DRM_DEBUG("  interrupted\n");
-                       return -ERESTARTSYS;
-               }
-               DRM_DEBUG("  awake\n");
-       }
-
-       left  = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
-       avail = DRM_BSZ - left;
-       send  = DRM_MIN(avail, count);
-
-       while (send) {
-               if (dev->buf_wp > dev->buf_rp) {
-                       cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
-               } else {
-                       cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
-               }
-               if (copy_to_user(buf, dev->buf_rp, cur))
-                       return -EFAULT;
-               dev->buf_rp += cur;
-               if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
-               send -= cur;
-       }
-       
-       wake_up_interruptible(&dev->buf_writers);
-       return DRM_MIN(avail, count);;
-}
-
-int drm_write_string(drm_device_t *dev, const char *s)
-{
-       int left   = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
-       int send   = strlen(s);
-       int count;
-
-       DRM_DEBUG("%d left, %d to send (%p, %p)\n",
-                 left, send, dev->buf_rp, dev->buf_wp);
-       
-       if (left == 1 || dev->buf_wp != dev->buf_rp) {
-               DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
-                         left,
-                         dev->buf_wp,
-                         dev->buf_rp);
-       }
-
-       while (send) {
-               if (dev->buf_wp >= dev->buf_rp) {
-                       count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
-                       if (count == left) --count; /* Leave a hole */
-               } else {
-                       count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
-               }
-               strncpy(dev->buf_wp, s, count);
-               dev->buf_wp += count;
-               if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
-               send -= count;
-       }
-
-#if LINUX_VERSION_CODE < 0x020315 && !defined(KILLFASYNCHASTHREEPARAMETERS)
-       /* The extra parameter to kill_fasync was added in 2.3.21, and is
-           _not_ present in _stock_ 2.2.14 and 2.2.15.  However, some
-           distributions patch 2.2.x kernels to add this parameter.  The
-           Makefile.linux attempts to detect this addition and defines
-           KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */
-       if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
-#else
-
-                               /* Parameter added in 2.3.21. */
-#if LINUX_VERSION_CODE < 0x020400
-       if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
-#else
-                               /* Type of first parameter changed in
-                                   Linux 2.4.0-test2... */
-       if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
-#endif
-#endif
-       DRM_DEBUG("waking\n");
-       wake_up_interruptible(&dev->buf_readers);
-       return 0;
-}
-
-unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
-{
-       drm_file_t   *priv = filp->private_data;
-       drm_device_t *dev  = priv->dev;
-
-       poll_wait(filp, &dev->buf_readers, wait);
-       if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM;
-       return 0;
-}
diff --git a/drivers/char/drm/gamma.h b/drivers/char/drm/gamma.h
new file mode 100644 (file)
index 0000000..232ed01
--- /dev/null
@@ -0,0 +1,93 @@
+/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
+ * Created: Mon Jan  4 08:58:31 1999 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>
+ */
+
+#ifndef __GAMMA_H__
+#define __GAMMA_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) gamma_##x
+
+/* General customization:
+ */
+#define __HAVE_MTRR                    1
+
+/* DMA customization:
+ */
+#define __HAVE_DMA                     1
+#define __HAVE_OLD_DMA                 1
+#define __HAVE_PCI_DMA                 1
+
+#define __HAVE_MULTIPLE_DMA_QUEUES     1
+#define __HAVE_DMA_WAITQUEUE           1
+
+#define __HAVE_DMA_WAITLIST            1
+#define __HAVE_DMA_FREELIST            1
+
+#define __HAVE_DMA_FLUSH               1
+#define __HAVE_DMA_SCHEDULE            1
+
+#define __HAVE_DMA_READY               1
+#define DRIVER_DMA_READY() do {                                                \
+       gamma_dma_ready(dev);                                           \
+} while (0)
+
+#define __HAVE_DMA_QUIESCENT           1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       /* FIXME ! */                                                   \
+       gamma_dma_quiescent_dual(dev);                                  \
+       return 0;                                                       \
+} while (0)
+
+#define __HAVE_DMA_IRQ                 1
+#define __HAVE_DMA_IRQ_BH              1
+#define DRIVER_PREINSTALL() do {                                       \
+       drm_gamma_private_t *dev_priv =                                 \
+                               (drm_gamma_private_t *)dev->dev_private;\
+       GAMMA_WRITE( GAMMA_GCOMMANDMODE,        0x00000000 );           \
+       GAMMA_WRITE( GAMMA_GDMACONTROL,         0x00000000 );           \
+} while (0)
+
+#define DRIVER_POSTINSTALL() do {                                      \
+       drm_gamma_private_t *dev_priv =                                 \
+                               (drm_gamma_private_t *)dev->dev_private;\
+       GAMMA_WRITE( GAMMA_GINTENABLE,          0x00002001 );           \
+       GAMMA_WRITE( GAMMA_COMMANDINTENABLE,    0x00000008 );           \
+       GAMMA_WRITE( GAMMA_GDELAYTIMER,         0x00039090 );           \
+} while (0)
+
+#define DRIVER_UNINSTALL() do {                                                \
+       drm_gamma_private_t *dev_priv =                                 \
+                               (drm_gamma_private_t *)dev->dev_private;\
+       GAMMA_WRITE( GAMMA_GDELAYTIMER,         0x00000000 );           \
+       GAMMA_WRITE( GAMMA_COMMANDINTENABLE,    0x00000000 );           \
+       GAMMA_WRITE( GAMMA_GINTENABLE,          0x00000000 );           \
+} while (0)
+
+#endif /* __GAMMA_H__ */
index 4854c56d591b5ff0addddec5f3e07aec2e67cd85..7510e2b5742b86e22f66f46ada8ee158f8fa97c4 100644 (file)
  * 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
  * 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>
  *
  */
 
 #define __NO_VERSION__
+#include "gamma.h"
 #include "drmP.h"
 #include "gamma_drv.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
+#include <linux/delay.h>
 
 
-/* WARNING!!! MAGIC NUMBER!!!  The number of regions already added to the
-   kernel must be specified here.  Currently, the number is 2. This must
-   match the order the X server uses for instantiating register regions ,
-   or must be passed in a new ioctl. */
-#define GAMMA_REG(reg)                                            \
-       (2                                                         \
-        + ((reg < 0x1000)                                         \
-           ? 0                                                    \
-           : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3))))
-
-#define GAMMA_OFF(reg)                                            \
-       ((reg < 0x1000)                                            \
-        ? reg                                                     \
-        : ((reg < 0x10000)                                        \
-           ? (reg - 0x1000)                                       \
-           : ((reg < 0x11000)                                     \
-              ? (reg - 0x10000)                                   \
-              : (reg - 0x11000))))
-
-#define GAMMA_BASE(reg)         ((unsigned long)dev->maplist[GAMMA_REG(reg)]->handle)
-#define GAMMA_ADDR(reg)         (GAMMA_BASE(reg) + GAMMA_OFF(reg))
-#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
-#define GAMMA_READ(reg)         GAMMA_DEREF(reg)
-#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
-
-#define GAMMA_BROADCASTMASK    0x9378
-#define GAMMA_COMMANDINTENABLE 0x0c48
-#define GAMMA_DMAADDRESS       0x0028
-#define GAMMA_DMACOUNT        0x0030
-#define GAMMA_FILTERMODE       0x8c00
-#define GAMMA_GCOMMANDINTFLAGS 0x0c50
-#define GAMMA_GCOMMANDMODE     0x0c40
-#define GAMMA_GCOMMANDSTATUS   0x0c60
-#define GAMMA_GDELAYTIMER      0x0c38
-#define GAMMA_GDMACONTROL      0x0060
-#define GAMMA_GINTENABLE       0x0808
-#define GAMMA_GINTFLAGS               0x0810
-#define GAMMA_INFIFOSPACE      0x0018
-#define GAMMA_OUTFIFOWORDS     0x0020
-#define GAMMA_OUTPUTFIFO       0x2000
-#define GAMMA_SYNC            0x8c40
-#define GAMMA_SYNC_TAG        0x0188
-
 static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
                                      unsigned long length)
 {
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
        GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address));
        while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4)
                ;
        GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
 }
 
-static inline void gamma_dma_quiescent_single(drm_device_t *dev)
+void gamma_dma_quiescent_single(drm_device_t *dev)
 {
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
        while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -97,15 +62,18 @@ static inline void gamma_dma_quiescent_single(drm_device_t *dev)
 
        GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
        GAMMA_WRITE(GAMMA_SYNC, 0);
-       
+
        do {
                while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
                        ;
        } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
 }
 
-static inline void gamma_dma_quiescent_dual(drm_device_t *dev)
+void gamma_dma_quiescent_dual(drm_device_t *dev)
 {
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
        while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
@@ -115,13 +83,13 @@ static inline void gamma_dma_quiescent_dual(drm_device_t *dev)
 
        GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
        GAMMA_WRITE(GAMMA_SYNC, 0);
-       
+
                                /* Read from first MX */
        do {
                while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
                        ;
        } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
-       
+
                                /* Read from second MX */
        do {
                while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
@@ -129,34 +97,39 @@ static inline void gamma_dma_quiescent_dual(drm_device_t *dev)
        } while (GAMMA_READ(GAMMA_OUTPUTFIFO + 0x10000) != GAMMA_SYNC_TAG);
 }
 
-static inline void gamma_dma_ready(drm_device_t *dev)
+void gamma_dma_ready(drm_device_t *dev)
 {
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
 }
 
 static inline int gamma_dma_is_ready(drm_device_t *dev)
 {
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
        return !GAMMA_READ(GAMMA_DMACOUNT);
 }
 
-static void gamma_dma_service(int irq, void *device, struct pt_regs *regs)
+void gamma_dma_service(int irq, void *device, struct pt_regs *regs)
 {
-       drm_device_t     *dev = (drm_device_t *)device;
-       drm_device_dma_t *dma = dev->dma;
-       
-       atomic_inc(&dev->total_irq);
+       drm_device_t        *dev      = (drm_device_t *)device;
+       drm_device_dma_t    *dma      = dev->dma;
+       drm_gamma_private_t *dev_priv =
+               (drm_gamma_private_t *)dev->dev_private;
+
+       atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */
        GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */
        GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8);
        GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001);
        if (gamma_dma_is_ready(dev)) {
                                /* Free previous buffer */
-               if (test_and_set_bit(0, &dev->dma_flag)) {
-                       atomic_inc(&dma->total_missed_free);
-                       return;
-               }
+               if (test_and_set_bit(0, &dev->dma_flag)) return;
                if (dma->this_buffer) {
-                       drm_free_buffer(dev, dma->this_buffer);
+                       gamma_free_buffer(dev, dma->this_buffer);
                        dma->this_buffer = NULL;
                }
                clear_bit(0, &dev->dma_flag);
@@ -179,11 +152,8 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
        cycles_t         dma_start, dma_stop;
 #endif
 
-       if (test_and_set_bit(0, &dev->dma_flag)) {
-               atomic_inc(&dma->total_missed_dma);
-               return -EBUSY;
-       }
-       
+       if (test_and_set_bit(0, &dev->dma_flag)) return -EBUSY;
+
 #if DRM_DMA_HISTOGRAM
        dma_start = get_cycles();
 #endif
@@ -202,20 +172,20 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
                  buf->context, buf->idx, length);
 
        if (buf->list == DRM_LIST_RECLAIM) {
-               drm_clear_next_buffer(dev);
-               drm_free_buffer(dev, buf);
+               gamma_clear_next_buffer(dev);
+               gamma_free_buffer(dev, buf);
                clear_bit(0, &dev->dma_flag);
                return -EINVAL;
        }
 
        if (!length) {
                DRM_ERROR("0 length buffer\n");
-               drm_clear_next_buffer(dev);
-               drm_free_buffer(dev, buf);
+               gamma_clear_next_buffer(dev);
+               gamma_free_buffer(dev, buf);
                clear_bit(0, &dev->dma_flag);
                return 0;
        }
-       
+
        if (!gamma_dma_is_ready(dev)) {
                clear_bit(0, &dev->dma_flag);
                return -EBUSY;
@@ -228,9 +198,8 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
                                  buf->idx, buf->pid);
                }
        } else {
-               if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
+               if (!locked && !gamma_lock_take(&dev->lock.hw_lock->lock,
                                              DRM_KERNEL_CONTEXT)) {
-                       atomic_inc(&dma->total_missed_lock);
                        clear_bit(0, &dev->dma_flag);
                        return -EBUSY;
                }
@@ -240,13 +209,14 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
            && !(dev->queuelist[buf->context]->flags
                 & _DRM_CONTEXT_PRESERVED)) {
                                /* PRE: dev->last_context != buf->context */
-               if (drm_context_switch(dev, dev->last_context, buf->context)) {
-                       drm_clear_next_buffer(dev);
-                       drm_free_buffer(dev, buf);
+               if (DRM(context_switch)(dev, dev->last_context,
+                                       buf->context)) {
+                       DRM(clear_next_buffer)(dev);
+                       DRM(free_buffer)(dev, buf);
                }
                retcode = -EBUSY;
                goto cleanup;
-                       
+
                                /* POST: we will wait for the context
                                   switch and will dispatch on a later call
                                   when dev->last_context == buf->context.
@@ -254,7 +224,7 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
                                   TIME! */
        }
 
-       drm_clear_next_buffer(dev);
+       gamma_clear_next_buffer(dev);
        buf->pending     = 1;
        buf->waiting     = 0;
        buf->list        = DRM_LIST_PEND;
@@ -263,14 +233,14 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
 #endif
 
        gamma_dma_dispatch(dev, address, length);
-       drm_free_buffer(dev, dma->this_buffer);
+       gamma_free_buffer(dev, dma->this_buffer);
        dma->this_buffer = buf;
 
-       atomic_add(length, &dma->total_bytes);
-       atomic_inc(&dma->total_dmas);
+       atomic_inc(&dev->counts[7]); /* _DRM_STAT_DMA */
+       atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
 
        if (!buf->while_locked && !dev->context_flag && !locked) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+               if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
                                  DRM_KERNEL_CONTEXT)) {
                        DRM_ERROR("\n");
                }
@@ -281,18 +251,18 @@ cleanup:
 
 #if DRM_DMA_HISTOGRAM
        dma_stop = get_cycles();
-       atomic_inc(&dev->histo.dma[drm_histogram_slot(dma_stop - dma_start)]);
+       atomic_inc(&dev->histo.dma[gamma_histogram_slot(dma_stop - dma_start)]);
 #endif
 
        return retcode;
 }
 
-static void gamma_dma_schedule_timer_wrapper(unsigned long dev)
+static void gamma_dma_timer_bh(unsigned long dev)
 {
        gamma_dma_schedule((drm_device_t *)dev, 0);
 }
 
-static void gamma_dma_schedule_tq_wrapper(void *dev)
+void gamma_dma_immediate_bh(void *dev)
 {
        gamma_dma_schedule(dev, 0);
 }
@@ -313,10 +283,10 @@ int gamma_dma_schedule(drm_device_t *dev, int locked)
 
        if (test_and_set_bit(0, &dev->interrupt_flag)) {
                                /* Not reentrant */
-               atomic_inc(&dma->total_missed_sched);
+               atomic_inc(&dev->counts[10]); /* _DRM_STAT_MISSED */
                return -EBUSY;
        }
-       missed = atomic_read(&dma->total_missed_sched);
+       missed = atomic_read(&dev->counts[10]);
 
 #if DRM_DMA_HISTOGRAM
        schedule_start = get_cycles();
@@ -333,23 +303,18 @@ again:
                                   because the lock could not be obtained
                                   or the DMA engine wasn't ready.  Try
                                   again. */
-               atomic_inc(&dma->total_tried);
-               if (!(retcode = gamma_do_dma(dev, locked))) {
-                       atomic_inc(&dma->total_hit);
-                       ++processed;
-               }
+               if (!(retcode = gamma_do_dma(dev, locked))) ++processed;
        } else {
                do {
-                       next = drm_select_queue(dev,
-                                            gamma_dma_schedule_timer_wrapper);
+                       next = gamma_select_queue(dev, gamma_dma_timer_bh);
                        if (next >= 0) {
                                q   = dev->queuelist[next];
-                               buf = drm_waitlist_get(&q->waitlist);
+                               buf = gamma_waitlist_get(&q->waitlist);
                                dma->next_buffer = buf;
                                dma->next_queue  = q;
                                if (buf && buf->list == DRM_LIST_RECLAIM) {
-                                       drm_clear_next_buffer(dev);
-                                       drm_free_buffer(dev, buf);
+                                       gamma_clear_next_buffer(dev);
+                                       gamma_free_buffer(dev, buf);
                                }
                        }
                } while (next >= 0 && !dma->next_buffer);
@@ -361,21 +326,19 @@ again:
        }
 
        if (--expire) {
-               if (missed != atomic_read(&dma->total_missed_sched)) {
-                       atomic_inc(&dma->total_lost);
+               if (missed != atomic_read(&dev->counts[10])) {
                        if (gamma_dma_is_ready(dev)) goto again;
                }
                if (processed && gamma_dma_is_ready(dev)) {
-                       atomic_inc(&dma->total_lost);
                        processed = 0;
                        goto again;
                }
        }
-       
+
        clear_bit(0, &dev->interrupt_flag);
-       
+
 #if DRM_DMA_HISTOGRAM
-       atomic_inc(&dev->histo.schedule[drm_histogram_slot(get_cycles()
+       atomic_inc(&dev->histo.schedule[gamma_histogram_slot(get_cycles()
                                                           - schedule_start)]);
 #endif
        return retcode;
@@ -400,7 +363,7 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
                if (signal_pending(current)) return -EINTR;
        }
        if (!(d->flags & _DRM_DMA_WHILE_LOCKED)) {
-               while (!drm_lock_take(&dev->lock.hw_lock->lock,
+               while (!gamma_lock_take(&dev->lock.hw_lock->lock,
                                      DRM_KERNEL_CONTEXT)) {
                        schedule();
                        if (signal_pending(current)) {
@@ -410,7 +373,6 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
                }
                ++must_free;
        }
-       atomic_inc(&dma->total_prio);
 
        for (i = 0; i < d->send_count; i++) {
                idx = d->send_indices[i];
@@ -461,15 +423,15 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
                        goto cleanup;
                }
                buf->pending = 1;
-               
+
                if (dev->last_context != buf->context
                    && !(dev->queuelist[buf->context]->flags
                         & _DRM_CONTEXT_PRESERVED)) {
                        add_wait_queue(&dev->context_wait, &entry);
                        current->state = TASK_INTERRUPTIBLE;
                                /* PRE: dev->last_context != buf->context */
-                       drm_context_switch(dev, dev->last_context,
-                                          buf->context);
+                       DRM(context_switch)(dev, dev->last_context,
+                                           buf->context);
                                /* POST: we will wait for the context
                                   switch and will dispatch on a later call
                                   when dev->last_context == buf->context.
@@ -494,11 +456,11 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
                buf->time_dispatched = buf->time_queued;
 #endif
                gamma_dma_dispatch(dev, address, length);
-               atomic_add(length, &dma->total_bytes);
-               atomic_inc(&dma->total_dmas);
-               
+               atomic_inc(&dev->counts[9]); /* _DRM_STAT_SPECIAL */
+               atomic_add(length, &dev->counts[8]); /* _DRM_STAT_PRIMARY */
+
                if (last_buf) {
-                       drm_free_buffer(dev, last_buf);
+                       gamma_free_buffer(dev, last_buf);
                }
                last_buf = buf;
        }
@@ -507,11 +469,11 @@ static int gamma_dma_priority(drm_device_t *dev, drm_dma_t *d)
 cleanup:
        if (last_buf) {
                gamma_dma_ready(dev);
-               drm_free_buffer(dev, last_buf);
+               gamma_free_buffer(dev, last_buf);
        }
-       
+
        if (must_free && !dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+               if (gamma_lock_free(dev, &dev->lock.hw_lock->lock,
                                  DRM_KERNEL_CONTEXT)) {
                        DRM_ERROR("\n");
                }
@@ -531,15 +493,15 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
                last_buf = dma->buflist[d->send_indices[d->send_count-1]];
                add_wait_queue(&last_buf->dma_wait, &entry);
        }
-       
-       if ((retcode = drm_dma_enqueue(dev, d))) {
+
+       if ((retcode = gamma_dma_enqueue(dev, d))) {
                if (d->flags & _DRM_DMA_BLOCK)
                        remove_wait_queue(&last_buf->dma_wait, &entry);
                return retcode;
        }
-       
+
        gamma_dma_schedule(dev, 0);
-       
+
        if (d->flags & _DRM_DMA_BLOCK) {
                DRM_DEBUG("%d waiting\n", current->pid);
                for (;;) {
@@ -558,7 +520,7 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
                if (!retcode
                    || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
                        if (!waitqueue_active(&last_buf->dma_wait)) {
-                               drm_free_buffer(dev, last_buf);
+                               gamma_free_buffer(dev, last_buf);
                        }
                }
                if (retcode) {
@@ -587,19 +549,13 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
 
        if (copy_from_user(&d, (drm_dma_t *)arg, sizeof(d)))
                return -EFAULT;
-       DRM_DEBUG("%d %d: %d send, %d req\n",
-                 current->pid, d.context, d.send_count, d.request_count);
 
-       if (d.context == DRM_KERNEL_CONTEXT || d.context >= dev->queue_slots) {
-               DRM_ERROR("Process %d using context %d\n",
-                         current->pid, d.context);
-               return -EINVAL;
-       }
        if (d.send_count < 0 || d.send_count > dma->buf_count) {
                DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
                          current->pid, d.send_count, dma->buf_count);
                return -EINVAL;
        }
+
        if (d.request_count < 0 || d.request_count > dma->buf_count) {
                DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
                          current->pid, d.request_count, dma->buf_count);
@@ -609,14 +565,14 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
        if (d.send_count) {
                if (d.flags & _DRM_DMA_PRIORITY)
                        retcode = gamma_dma_priority(dev, &d);
-               else 
+               else
                        retcode = gamma_dma_send_buffers(dev, &d);
        }
 
        d.granted_count = 0;
 
        if (!retcode && d.request_count) {
-               retcode = drm_dma_get_buffers(dev, &d);
+               retcode = gamma_dma_get_buffers(dev, &d);
        }
 
        DRM_DEBUG("%d returning, granted = %d\n",
@@ -626,211 +582,3 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
 
        return retcode;
 }
-
-int gamma_irq_install(drm_device_t *dev, int irq)
-{
-       int retcode;
-
-       if (!irq)     return -EINVAL;
-       
-       down(&dev->struct_sem);
-       if (dev->irq) {
-               up(&dev->struct_sem);
-               return -EBUSY;
-       }
-       dev->irq = irq;
-       up(&dev->struct_sem);
-       
-       DRM_DEBUG("%d\n", irq);
-
-       dev->context_flag     = 0;
-       dev->interrupt_flag   = 0;
-       dev->dma_flag         = 0;
-       
-       dev->dma->next_buffer = NULL;
-       dev->dma->next_queue  = NULL;
-       dev->dma->this_buffer = NULL;
-
-       INIT_LIST_HEAD(&dev->tq.list);
-       dev->tq.sync          = 0;
-       dev->tq.routine       = gamma_dma_schedule_tq_wrapper;
-       dev->tq.data          = dev;
-
-
-                               /* Before installing handler */
-       GAMMA_WRITE(GAMMA_GCOMMANDMODE, 0);
-       GAMMA_WRITE(GAMMA_GDMACONTROL, 0);
-       
-                               /* Install handler */
-       if ((retcode = request_irq(dev->irq,
-                                  gamma_dma_service,
-                                  0,
-                                  dev->devname,
-                                  dev))) {
-               down(&dev->struct_sem);
-               dev->irq = 0;
-               up(&dev->struct_sem);
-               return retcode;
-       }
-
-                               /* After installing handler */
-       GAMMA_WRITE(GAMMA_GINTENABLE,       0x2001);
-       GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0x0008);
-       GAMMA_WRITE(GAMMA_GDELAYTIMER,     0x39090);
-       
-       return 0;
-}
-
-int gamma_irq_uninstall(drm_device_t *dev)
-{
-       int irq;
-
-       down(&dev->struct_sem);
-       irq      = dev->irq;
-       dev->irq = 0;
-       up(&dev->struct_sem);
-       
-       if (!irq) return -EINVAL;
-       
-       DRM_DEBUG("%d\n", irq);
-       
-       GAMMA_WRITE(GAMMA_GDELAYTIMER,      0);
-       GAMMA_WRITE(GAMMA_COMMANDINTENABLE, 0);
-       GAMMA_WRITE(GAMMA_GINTENABLE,       0);
-       free_irq(irq, dev);
-
-       return 0;
-}
-
-
-int gamma_control(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_control_t   ctl;
-       int             retcode;
-       
-       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
-               return -EFAULT;
-       
-       switch (ctl.func) {
-       case DRM_INST_HANDLER:
-               if ((retcode = gamma_irq_install(dev, ctl.irq)))
-                       return retcode;
-               break;
-       case DRM_UNINST_HANDLER:
-               if ((retcode = gamma_irq_uninstall(dev)))
-                       return retcode;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       DECLARE_WAITQUEUE(entry, current);
-       int               ret   = 0;
-       drm_lock_t        lock;
-       drm_queue_t       *q;
-#if DRM_DMA_HISTOGRAM
-       cycles_t          start;
-
-       dev->lck_start = start = get_cycles();
-#endif
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                 lock.context, current->pid, dev->lock.hw_lock->lock,
-                 lock.flags);
-
-       if (lock.context < 0 || lock.context >= dev->queue_count)
-               return -EINVAL;
-       q = dev->queuelist[lock.context];
-       
-       ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
-
-       if (!ret) {
-               if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
-                   != lock.context) {
-                       long j = jiffies - dev->lock.lock_time;
-
-                       if (j > 0 && j <= DRM_LOCK_SLICE) {
-                               /* Can't take lock if we just had it and
-                                  there is contention. */
-                               current->state = TASK_INTERRUPTIBLE;
-                               schedule_timeout(j);
-                       }
-               }
-               add_wait_queue(&dev->lock.lock_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!dev->lock.hw_lock) {
-                               /* Device has been unregistered */
-                               ret = -EINTR;
-                               break;
-                       }
-                       if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                         lock.context)) {
-                               dev->lock.pid       = current->pid;
-                               dev->lock.lock_time = jiffies;
-                               atomic_inc(&dev->total_locks);
-                               atomic_inc(&q->total_locks);
-                               break;  /* Got lock */
-                       }
-                       
-                               /* Contention */
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->lock.lock_queue, &entry);
-       }
-
-       drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
-       
-       if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
-               if (lock.flags & _DRM_LOCK_READY)
-                       gamma_dma_ready(dev);
-               if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                       if (gamma_found() == 1) {
-                               gamma_dma_quiescent_single(dev);
-                       } else {
-                               gamma_dma_quiescent_dual(dev);
-                       }
-               }
-       }
-       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-#if DRM_DMA_HISTOGRAM
-       atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
-#endif
-       
-       return ret;
-}
index a17bc1a9f6033253b4d86e9839a19f6166cddbfa..c05465c5dad95fede92ac458d3f75675bae5be02 100644 (file)
  *
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #include <linux/config.h>
+#include "gamma.h"
 #include "drmP.h"
 #include "gamma_drv.h"
 
-#ifndef PCI_DEVICE_ID_3DLABS_GAMMA
-#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008
-#endif
-#ifndef PCI_DEVICE_ID_3DLABS_MX
-#define PCI_DEVICE_ID_3DLABS_MX 0x0006
-#endif
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
 
-#define GAMMA_NAME      "gamma"
-#define GAMMA_DESC      "3dlabs GMX 2000"
-#define GAMMA_DATE      "20000910"
-#define GAMMA_MAJOR     1
-#define GAMMA_MINOR     0
-#define GAMMA_PATCHLEVEL 0
+#define DRIVER_NAME            "gamma"
+#define DRIVER_DESC            "3DLabs gamma"
+#define DRIVER_DATE            "20010216"
 
-static drm_device_t          gamma_device;
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
 
-static struct file_operations gamma_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#endif
-       open:    gamma_open,
-       flush:   drm_flush,
-       release: gamma_release,
-       ioctl:   gamma_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
+#define DRIVER_IOCTLS                                                    \
+       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]        = { gamma_dma,       1, 0 }
 
-static struct miscdevice      gamma_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  GAMMA_NAME,
-       fops:  &gamma_fops,
-};
 
-static drm_ioctl_desc_t              gamma_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]    = { gamma_version,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]  = { drm_getmagic,    0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]  = { drm_irq_busid,   0, 1 },
+#define __HAVE_COUNTERS                5
+#define __HAVE_COUNTER6                _DRM_STAT_IRQ
+#define __HAVE_COUNTER7                _DRM_STAT_DMA
+#define __HAVE_COUNTER8                _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER9                _DRM_STAT_SPECIAL
+#define __HAVE_COUNTER10       _DRM_STAT_MISSED
 
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]      = { drm_block,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]    = { drm_unblock,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]    = { gamma_control,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]    = { drm_addmap,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]   = { drm_addbufs,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]  = { drm_markbufs,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]  = { drm_infobufs,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]   = { drm_mapbufs,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]  = { drm_freebufs,    1, 0 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]    = { drm_addctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]     = { drm_rmctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]    = { drm_modctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]    = { drm_getctx,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]    = { drm_newctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]    = { drm_resctx,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]   = { drm_adddraw,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]    = { drm_rmdraw,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]        = { gamma_dma,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]       = { gamma_lock,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]     = { gamma_unlock,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]     = { drm_finish,      1, 0 },
-};
-#define GAMMA_IOCTL_COUNT DRM_ARRAY_SIZE(gamma_ioctls)
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
-#ifdef MODULE
-static char                  *gamma = NULL;
-#endif
-static int                   devices = 0;
-
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("3dlabs GMX 2000");
-MODULE_PARM(gamma, "s");
-MODULE_PARM(devices, "i");
-MODULE_PARM_DESC(devices,
-                "devices=x, where x is the number of MX chips on card\n");
 #ifndef MODULE
-/* gamma_options is called by the kernel to parse command-line options
+/* DRM(options) is called by the kernel to parse command-line options
  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_options.
+ * routine, drm_parse_drm.
  */
 
-
-static int __init gamma_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init gamma_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("gamma=", gamma_options);
-#endif
-
-static int gamma_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       drm_dma_setup(dev);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-#if DRM_DMA_HISTO
-       memset(&dev->histo, 0, sizeof(dev->histo));
-#endif
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int gamma_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       if (dev->irq) gamma_irq_uninstall(dev);
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
+__setup( DRIVER_NAME "=", gamma_options );
 #endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                   handled in the AGP/GART driver. */
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       if (dev->queuelist) {
-               for (i = 0; i < dev->queue_count; i++) {
-                       drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
-                       if (dev->queuelist[i]) {
-                               drm_free(dev->queuelist[i],
-                                        sizeof(*dev->queuelist[0]),
-                                        DRM_MEM_QUEUES);
-                               dev->queuelist[i] = NULL;
-                       }
-               }
-               drm_free(dev->queuelist,
-                        dev->queue_slots * sizeof(*dev->queuelist),
-                        DRM_MEM_QUEUES);
-               dev->queuelist   = NULL;
-       }
-
-       drm_dma_takedown(dev);
-
-       dev->queue_count     = 0;
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-int gamma_found(void)
-{
-       return devices;
-}
-
-int gamma_find_devices(void)
-{
-       struct pci_dev *d = NULL, *one = NULL, *two = NULL;
-
-       d = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_GAMMA,d);
-       if (!d) return 0;
-
-       one = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,d);
-       if (!one) return 0;
-
-       /* Make sure it's on the same card, if not - no MX's found */
-       if (PCI_SLOT(d->devfn) != PCI_SLOT(one->devfn)) return 0;
-
-       two = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,one);
-       if (!two) return 1;
-
-       /* Make sure it's on the same card, if not - only 1 MX found */
-       if (PCI_SLOT(d->devfn) != PCI_SLOT(two->devfn)) return 1;
-
-       /* Two MX's found - we don't currently support more than 2 */
-       return 2;
-}
-
-/* gamma_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init gamma_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &gamma_device;
-
-       DRM_DEBUG("\n");
 
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
 
-#ifdef MODULE
-       drm_parse_options(gamma);
-#endif
-       devices = gamma_find_devices();
-       if (devices == 0) return -1;
-
-       if ((retcode = misc_register(&gamma_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", GAMMA_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, gamma_misc.minor);
-       dev->name   = GAMMA_NAME;
-
-       drm_mem_init();
-       drm_proc_init(dev);
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d with %d MX devices\n",
-                GAMMA_NAME,
-                GAMMA_MAJOR,
-                GAMMA_MINOR,
-                GAMMA_PATCHLEVEL,
-                GAMMA_DATE,
-                gamma_misc.minor,
-                devices);
-
-       return 0;
-}
-
-/* gamma_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit gamma_cleanup(void)
-{
-       drm_device_t          *dev = &gamma_device;
-
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&gamma_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       gamma_takedown(dev);
-}
-
-module_init(gamma_init);
-module_exit(gamma_cleanup);
-
-
-int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                \
-       len = strlen(value);                                 \
-       if (len > name##_len) len = name##_len;              \
-       name##_len = strlen(value);                          \
-       if (len && name) {                                   \
-               if (copy_to_user(name, value, len))          \
-                       return -EFAULT;                      \
-       }
-
-       version.version_major      = GAMMA_MAJOR;
-       version.version_minor      = GAMMA_MINOR;
-       version.version_patchlevel = GAMMA_PATCHLEVEL;
-
-       DRM_COPY(version.name, GAMMA_NAME);
-       DRM_COPY(version.date, GAMMA_DATE);
-       DRM_COPY(version.desc, GAMMA_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int gamma_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &gamma_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return gamma_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-       return retcode;
-}
-
-int gamma_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev = priv->dev;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_release(inode, filp))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_close);
-               spin_lock(&dev->count_lock);
-               if (!--dev->open_count) {
-                       if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                               DRM_ERROR("Device busy: %d %d\n",
-                                         atomic_read(&dev->ioctl_count),
-                                         dev->blocked);
-                               spin_unlock(&dev->count_lock);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return gamma_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-       unlock_kernel();
-       return retcode;
-}
-
-/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-
-int gamma_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= GAMMA_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &gamma_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-
-int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-       gamma_dma_schedule(dev, 1);
-       if (!dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
-#if DRM_DMA_HISTOGRAM
-       atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
-                                                      - dev->lck_start)]);
-#endif
-
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lists.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
index e9ce39589707903e1f7f1dfbc2f5bc0718dbf447..68b520700ac6006db655e894a1917ebb6f5d1ed0 100644 (file)
  * 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
  * 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>
- * 
+ *
  */
 
 #ifndef _GAMMA_DRV_H_
 #define _GAMMA_DRV_H_
 
-                               /* gamma_drv.c */
-extern int  gamma_version(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  gamma_open(struct inode *inode, struct file *filp);
-extern int  gamma_release(struct inode *inode, struct file *filp);
-extern int  gamma_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  gamma_lock(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  gamma_unlock(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
+
+typedef struct drm_gamma_private {
+       drm_map_t *buffers;
+       drm_map_t *mmio0;
+       drm_map_t *mmio1;
+       drm_map_t *mmio2;
+       drm_map_t *mmio3;
+} drm_gamma_private_t;
+
+#define LOCK_TEST_WITH_RETURN( dev )                                   \
+do {                                                                   \
+       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||           \
+            dev->lock.pid != current->pid ) {                          \
+               DRM_ERROR( "%s called without lock held\n",             \
+                          __FUNCTION__ );                              \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+
+extern void gamma_dma_ready(drm_device_t *dev);
+extern void gamma_dma_quiescent_single(drm_device_t *dev);
+extern void gamma_dma_quiescent_dual(drm_device_t *dev);
 
                                /* gamma_dma.c */
 extern int  gamma_dma_schedule(drm_device_t *dev, int locked);
 extern int  gamma_dma(struct inode *inode, struct file *filp,
                      unsigned int cmd, unsigned long arg);
-extern int  gamma_irq_install(drm_device_t *dev, int irq);
-extern int  gamma_irq_uninstall(drm_device_t *dev);
-extern int  gamma_control(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
 extern int  gamma_find_devices(void);
 extern int  gamma_found(void);
 
+
+#define GAMMA_OFF(reg)                                            \
+       ((reg < 0x1000)                                            \
+        ? reg                                                     \
+        : ((reg < 0x10000)                                        \
+           ? (reg - 0x1000)                                       \
+           : ((reg < 0x11000)                                     \
+              ? (reg - 0x10000)                                   \
+              : (reg - 0x11000))))
+
+#define GAMMA_BASE(reg)         ((unsigned long)                                    \
+                         ((reg < 0x1000)    ? dev_priv->mmio0->handle :     \
+                          ((reg < 0x10000)  ? dev_priv->mmio1->handle :     \
+                           ((reg < 0x11000) ? dev_priv->mmio2->handle :     \
+                                              dev_priv->mmio3->handle))))
+       
+#define GAMMA_ADDR(reg)         (GAMMA_BASE(reg) + GAMMA_OFF(reg))
+#define GAMMA_DEREF(reg) *(__volatile__ int *)GAMMA_ADDR(reg)
+#define GAMMA_READ(reg)         GAMMA_DEREF(reg)
+#define GAMMA_WRITE(reg,val) do { GAMMA_DEREF(reg) = val; } while (0)
+
+#define GAMMA_BROADCASTMASK    0x9378
+#define GAMMA_COMMANDINTENABLE 0x0c48
+#define GAMMA_DMAADDRESS       0x0028
+#define GAMMA_DMACOUNT        0x0030
+#define GAMMA_FILTERMODE       0x8c00
+#define GAMMA_GCOMMANDINTFLAGS 0x0c50
+#define GAMMA_GCOMMANDMODE     0x0c40
+#define GAMMA_GCOMMANDSTATUS   0x0c60
+#define GAMMA_GDELAYTIMER      0x0c38
+#define GAMMA_GDMACONTROL      0x0060
+#define GAMMA_GINTENABLE       0x0808
+#define GAMMA_GINTFLAGS               0x0810
+#define GAMMA_INFIFOSPACE      0x0018
+#define GAMMA_OUTFIFOWORDS     0x0020
+#define GAMMA_OUTPUTFIFO       0x2000
+#define GAMMA_SYNC            0x8c40
+#define GAMMA_SYNC_TAG        0x0188
+
 #endif
diff --git a/drivers/char/drm/i810.h b/drivers/char/drm/i810.h
new file mode 100644 (file)
index 0000000..a5152bc
--- /dev/null
@@ -0,0 +1,116 @@
+/* i810.h -- Intel i810/i815 DRM template customization -*- linux-c -*-
+ * Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __I810_H__
+#define __I810_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) i810_##x
+
+/* General customization:
+ */
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+
+/* Driver customization:
+ */
+#define __HAVE_RELEASE         1
+#define DRIVER_RELEASE() do {                                          \
+       i810_reclaim_buffers( dev, priv->pid );                         \
+} while (0)
+
+/* DMA customization:
+ */
+#define __HAVE_DMA             1
+#define __HAVE_DMA_QUEUE       1
+#define __HAVE_DMA_WAITLIST    1
+#define __HAVE_DMA_RECLAIM     1
+
+#define __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       i810_dma_quiescent( dev );                                      \
+} while (0)
+
+#define __HAVE_DMA_IRQ         1
+#define __HAVE_DMA_IRQ_BH      1
+#define __HAVE_SHARED_IRQ       1
+#define DRIVER_PREINSTALL() do {                                       \
+       drm_i810_private_t *dev_priv =                                  \
+               (drm_i810_private_t *)dev->dev_private;                 \
+       u16 tmp;                                                        \
+       tmp = I810_READ16( I810REG_HWSTAM );                            \
+       tmp = tmp & 0x6000;                                             \
+       I810_WRITE16( I810REG_HWSTAM, tmp );                            \
+                                                                       \
+       tmp = I810_READ16( I810REG_INT_MASK_R );                        \
+       tmp = tmp & 0x6000;             /* Unmask interrupts */         \
+       I810_WRITE16( I810REG_INT_MASK_R, tmp );                        \
+       tmp = I810_READ16( I810REG_INT_ENABLE_R );                      \
+       tmp = tmp & 0x6000;             /* Disable all interrupts */    \
+       I810_WRITE16( I810REG_INT_ENABLE_R, tmp );                      \
+} while (0)
+
+#define DRIVER_POSTINSTALL() do {                                      \
+       drm_i810_private_t *dev_priv =                                  \
+               (drm_i810_private_t *)dev->dev_private;                 \
+       u16 tmp;                                                        \
+       tmp = I810_READ16( I810REG_INT_ENABLE_R );                      \
+       tmp = tmp & 0x6000;                                             \
+       tmp = tmp | 0x0003;     /* Enable bp & user interrupts */       \
+       I810_WRITE16( I810REG_INT_ENABLE_R, tmp );                      \
+} while (0)
+
+#define DRIVER_UNINSTALL() do {                                                \
+       drm_i810_private_t *dev_priv =                                  \
+               (drm_i810_private_t *)dev->dev_private;                 \
+       u16 tmp;                                                        \
+       if ( dev_priv ) {                                               \
+               tmp = I810_READ16( I810REG_INT_IDENTITY_R );            \
+               tmp = tmp & ~(0x6000);  /* Clear all interrupts */      \
+               if ( tmp != 0 )                                         \
+                       I810_WRITE16( I810REG_INT_IDENTITY_R, tmp );    \
+                                                                       \
+               tmp = I810_READ16( I810REG_INT_ENABLE_R );              \
+               tmp = tmp & 0x6000;     /* Disable all interrupts */    \
+               I810_WRITE16( I810REG_INT_ENABLE_R, tmp );              \
+       }                                                               \
+} while (0)
+
+/* Buffer customization:
+ */
+
+#define DRIVER_BUF_PRIV_T      drm_i810_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_i810_private_t *)((dev)->dev_private))->buffer_map
+
+#endif
diff --git a/drivers/char/drm/i810_bufs.c b/drivers/char/drm/i810_bufs.c
deleted file mode 100644 (file)
index 89e2d68..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/* i810_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
- * Created: Thu Jan 6 01:47:26 2000 by jhartmann@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *         Jeff Hartmann <jhartmann@valinux.com>
- * 
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "i810_drv.h"
-#include "linux/un.h"
-
-int i810_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
-{
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->dev;
-       drm_device_dma_t *dma = dev->dma;
-       drm_buf_desc_t request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       count = request.count;
-       order = drm_order(request.size);
-       size    = 1 << order;
-       agp_offset = request.agp_start;
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
-       page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-       total = PAGE_SIZE << page_order;
-       byte_count = 0;
-   
-       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-   
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-
-       if(count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -EINVAL;
-       }
-          
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -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 = offset;
-               buf->bus_address = dev->agp->base + agp_offset + offset;
-               buf->address = (void *)(agp_offset + offset + dev->agp->base);
-               buf->next = NULL;
-               buf->waiting = 0;
-               buf->pending = 0;
-               init_waitqueue_head(&buf->dma_wait);
-               buf->pid = 0;
-
-               buf->dev_private = drm_alloc(sizeof(drm_i810_buf_priv_t), 
-                                            DRM_MEM_BUFS);
-               buf->dev_priv_size = sizeof(drm_i810_buf_priv_t);
-               memset(buf->dev_private, 0, sizeof(drm_i810_buf_priv_t));
-
-#if DRM_DMA_HISTOGRAM
-               buf->time_queued = 0;
-               buf->time_dispatched = 0;
-               buf->time_completed = 0;
-               buf->time_freed = 0;
-#endif
-               offset = offset + alignment;
-               entry->buf_count++;
-               byte_count += PAGE_SIZE << page_order;
-      
-               DRM_DEBUG("buffer %d @ %p\n",
-                         entry->buf_count, buf->address);
-       }
-   
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-   
-       dma->buf_count  += entry->buf_count;
-       dma->byte_count += byte_count;
-       drm_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-   
-       up(&dev->struct_sem);
-   
-       request.count = entry->buf_count;
-       request.size  = size;
-   
-       if (copy_to_user((drm_buf_desc_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-   
-       atomic_dec(&dev->buf_alloc);
-       dma->flags = _DRM_DMA_USE_AGP;
-       return 0;
-}
-
-int i810_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_buf_desc_t   request;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       if(request.flags & _DRM_AGP_BUFFER)
-               return i810_addbufs_agp(inode, filp, cmd, arg);
-       else
-               return -EINVAL;
-}
-
-int i810_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_info_t   request;
-       int              i;
-       int              count;
-
-       if (!dma) return -EINVAL;
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_info_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       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) {
-                               if (copy_to_user(&request.list[count].count,
-                                                &dma->bufs[i].buf_count,
-                                                sizeof(dma->bufs[0]
-                                                       .buf_count)) ||
-                                   copy_to_user(&request.list[count].size,
-                                                &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size)) ||
-                                   copy_to_user(&request.list[count].low_mark,
-                                                &dma->bufs[i]
-                                                .freelist.low_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.low_mark)) ||
-                                   copy_to_user(&request.list[count]
-                                                .high_mark,
-                                                &dma->bufs[i]
-                                                .freelist.high_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.high_mark)))
-                                       return -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;
-
-       if (copy_to_user((drm_buf_info_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-       
-       return 0;
-}
-
-int i810_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_desc_t   request;
-       int              order;
-       drm_buf_entry_t  *entry;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       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 -EINVAL;
-       entry = &dma->bufs[order];
-
-       if (request.low_mark < 0 || request.low_mark > entry->buf_count)
-               return -EINVAL;
-       if (request.high_mark < 0 || request.high_mark > entry->buf_count)
-               return -EINVAL;
-
-       entry->freelist.low_mark  = request.low_mark;
-       entry->freelist.high_mark = request.high_mark;
-       
-       return 0;
-}
-
-int i810_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_free_t   request;
-       int              i;
-       int              idx;
-       drm_buf_t        *buf;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_free_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       DRM_DEBUG("%d\n", request.count);
-       for (i = 0; i < request.count; i++) {
-               if (copy_from_user(&idx,
-                                  &request.list[i],
-                                  sizeof(idx)))
-                       return -EFAULT;
-               if (idx < 0 || idx >= dma->buf_count) {
-                       DRM_ERROR("Index %d (of %d max)\n",
-                                 idx, dma->buf_count - 1);
-                       return -EINVAL;
-               }
-               buf = dma->buflist[idx];
-               if (buf->pid != current->pid) {
-                       DRM_ERROR("Process %d freeing buffer owned by %d\n",
-                                 current->pid, buf->pid);
-                       return -EINVAL;
-               }
-               drm_free_buffer(dev, buf);
-       }
-       
-       return 0;
-}
-
diff --git a/drivers/char/drm/i810_context.c b/drivers/char/drm/i810_context.c
deleted file mode 100644 (file)
index c331bee..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/* i810_context.c -- IOCTLs for i810 contexts -*- linux-c -*-
- * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "i810_drv.h"
-
-static int i810_alloc_queue(drm_device_t *dev)
-{
-       int temp = drm_ctxbitmap_next(dev);
-       DRM_DEBUG("i810_alloc_queue: %d\n", temp);
-       return temp;
-}
-
-int i810_context_switch(drm_device_t *dev, int old, int new)
-{
-        char        buf[64];
-
-        atomic_inc(&dev->total_ctx);
-
-        if (test_and_set_bit(0, &dev->context_flag)) {
-                DRM_ERROR("Reentering -- FIXME\n");
-                return -EBUSY;
-        }
-
-#if DRM_DMA_HISTOGRAM
-        dev->ctx_start = get_cycles();
-#endif
-        
-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-        if (new == dev->last_context) {
-                clear_bit(0, &dev->context_flag);
-                return 0;
-        }
-        
-        if (drm_flags & DRM_FLAG_NOCTX) {
-                i810_context_switch_complete(dev, new);
-        } else {
-                sprintf(buf, "C %d %d\n", old, new);
-                drm_write_string(dev, buf);
-        }
-        
-        return 0;
-}
-
-int i810_context_switch_complete(drm_device_t *dev, int new)
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-        
-        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. */
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                      - dev->ctx_start)]);
-                   
-#endif
-        clear_bit(0, &dev->context_flag);
-        wake_up(&dev->context_wait);
-        
-        return 0;
-}
-
-int i810_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i],
-                                        &i,
-                                        sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-int i810_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = i810_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Skip kernel's context and get a new one. */
-               ctx.handle = i810_alloc_queue(dev);
-       }
-        if (ctx.handle == -1) {
-               DRM_DEBUG("Not enough free contexts.\n");
-                               /* Should this return -EBUSY instead? */
-               return -ENOMEM;
-       }
-       DRM_DEBUG("%d\n", ctx.handle);
-       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int i810_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       /* This does nothing for the i810 */
-       return 0;
-}
-
-int i810_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       /* This is 0, because we don't hanlde any context flags */
-       ctx.flags = 0;
-       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int i810_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return i810_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int i810_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       i810_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int i810_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       if(ctx.handle != DRM_KERNEL_CONTEXT) {
-               drm_ctxbitmap_free(dev, ctx.handle);
-       }
-       
-       return 0;
-}
index a8ba4113ec879b4c6497dc35ac28533c694cb4cb..d6933d5764df0abdb47b9f27d6824e680a6d44ab 100644 (file)
  * 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
@@ -31,6 +31,7 @@
  */
 
 #define __NO_VERSION__
+#include "i810.h"
 #include "drmP.h"
 #include "i810_drv.h"
 #include <linux/interrupt.h>   /* For task queue support */
 #define I810_BUF_UNMAPPED 0
 #define I810_BUF_MAPPED   1
 
-#define I810_REG(reg)          2
-#define I810_BASE(reg)         ((unsigned long) \
-                               dev->maplist[I810_REG(reg)]->handle)
-#define I810_ADDR(reg)         (I810_BASE(reg) + reg)
-#define I810_DEREF(reg)                *(__volatile__ int *)I810_ADDR(reg)
-#define I810_READ(reg)         I810_DEREF(reg)
-#define I810_WRITE(reg,val)    do { I810_DEREF(reg) = val; } while (0)
-#define I810_DEREF16(reg)      *(__volatile__ u16 *)I810_ADDR(reg)
-#define I810_READ16(reg)       I810_DEREF16(reg)
-#define I810_WRITE16(reg,val)  do { I810_DEREF16(reg) = val; } while (0)
-
 #define RING_LOCALS    unsigned int outring, ringmask; volatile char *virt;
 
 #define BEGIN_LP_RING(n) do {                          \
@@ -107,14 +97,14 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev)
        drm_device_dma_t *dma = dev->dma;
        int              i;
        int              used;
-   
+
        /* Linear search might not be the best solution */
 
        for (i = 0; i < dma->buf_count; i++) {
                drm_buf_t *buf = dma->buflist[ i ];
                drm_i810_buf_priv_t *buf_priv = buf->dev_private;
                /* In use is already a pointer */
-               used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, 
+               used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
                               I810_BUF_CLIENT);
                if(used == I810_BUF_FREE) {
                        return buf;
@@ -131,26 +121,26 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf)
 {
        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
        int used;
-   
+
        /* In use is already a pointer */
        used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
        if(used != I810_BUF_CLIENT) {
                DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
                return -EINVAL;
        }
-   
+
        return 0;
 }
 
 static struct file_operations i810_buffer_fops = {
-       open:    i810_open,
-       flush:   drm_flush,
-       release: i810_release,
-       ioctl:   i810_ioctl,
+       open:    DRM(open),
+       flush:   DRM(flush),
+       release: DRM(release),
+       ioctl:   DRM(ioctl),
        mmap:    i810_mmap_buffers,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
+       read:    DRM(read),
+       fasync:  DRM(fasync),
+       poll:    DRM(poll),
 };
 
 int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
@@ -166,10 +156,10 @@ int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
        dev_priv = dev->dev_private;
        buf      = dev_priv->mmap_buffer;
        buf_priv = buf->dev_private;
-   
+
        vma->vm_flags |= (VM_IO | VM_DONTCOPY);
        vma->vm_file = filp;
-   
+
        buf_priv->currently_mapped = I810_BUF_MAPPED;
        unlock_kernel();
 
@@ -192,13 +182,17 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
        if(buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL;
 
        if(VM_DONTCOPY != 0) {
-               down_write(&current->mm->mmap_sem);
+#if LINUX_VERSION_CODE <= 0x020402
+               down( &current->mm->mmap_sem );
+#else
+               down_write( &current->mm->mmap_sem );
+#endif
                old_fops = filp->f_op;
                filp->f_op = &i810_buffer_fops;
                dev_priv->mmap_buffer = buf;
-               buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, 
+               buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total,
                                                    PROT_READ|PROT_WRITE,
-                                                   MAP_SHARED, 
+                                                   MAP_SHARED,
                                                    buf->bus_address);
                dev_priv->mmap_buffer = NULL;
                filp->f_op = old_fops;
@@ -208,7 +202,11 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
                        retcode = (signed int)buf_priv->virtual;
                        buf_priv->virtual = 0;
                }
-               up_write(&current->mm->mmap_sem);
+#if LINUX_VERSION_CODE <= 0x020402
+               up( &current->mm->mmap_sem );
+#else
+               up_write( &current->mm->mmap_sem );
+#endif
        } else {
                buf_priv->virtual = buf_priv->kernel_virtual;
                buf_priv->currently_mapped = I810_BUF_MAPPED;
@@ -222,18 +220,26 @@ static int i810_unmap_buffer(drm_buf_t *buf)
        int retcode = 0;
 
        if(VM_DONTCOPY != 0) {
-               if(buf_priv->currently_mapped != I810_BUF_MAPPED) 
+               if(buf_priv->currently_mapped != I810_BUF_MAPPED)
                        return -EINVAL;
-               down_write(&current->mm->mmap_sem);
+#if LINUX_VERSION_CODE <= 0x020402
+               down( &current->mm->mmap_sem );
+#else
+               down_write( &current->mm->mmap_sem );
+#endif
 #if LINUX_VERSION_CODE < 0x020399
-               retcode = do_munmap((unsigned long)buf_priv->virtual, 
+               retcode = do_munmap((unsigned long)buf_priv->virtual,
                                    (size_t) buf->total);
 #else
-               retcode = do_munmap(current->mm, 
-                                   (unsigned long)buf_priv->virtual, 
+               retcode = do_munmap(current->mm,
+                                   (unsigned long)buf_priv->virtual,
                                    (size_t) buf->total);
 #endif
-               up_write(&current->mm->mmap_sem);
+#if LINUX_VERSION_CODE <= 0x020402
+               up( &current->mm->mmap_sem );
+#else
+               up_write( &current->mm->mmap_sem );
+#endif
        }
        buf_priv->currently_mapped = I810_BUF_UNMAPPED;
        buf_priv->virtual = 0;
@@ -241,7 +247,7 @@ static int i810_unmap_buffer(drm_buf_t *buf)
        return retcode;
 }
 
-static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, 
+static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
                               struct file *filp)
 {
        drm_file_t        *priv   = filp->private_data;
@@ -255,7 +261,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
                DRM_DEBUG("retcode=%d\n", retcode);
                return retcode;
        }
-   
+
        retcode = i810_map_buffer(buf, filp);
        if(retcode) {
                i810_freelist_put(dev, buf);
@@ -263,7 +269,7 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
                return retcode;
        }
        buf->pid     = priv->pid;
-       buf_priv = buf->dev_private;    
+       buf_priv = buf->dev_private;
        d->granted = 1;
        d->request_idx = buf->idx;
        d->request_size = buf->total;
@@ -275,22 +281,22 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d,
 static unsigned long i810_alloc_page(drm_device_t *dev)
 {
        unsigned long address;
-   
+
        address = __get_free_page(GFP_KERNEL);
-       if(address == 0UL) 
+       if(address == 0UL)
                return 0;
-       
+
        atomic_inc(&virt_to_page(address)->count);
        set_bit(PG_locked, &virt_to_page(address)->flags);
-   
+
        return address;
 }
 
 static void i810_free_page(drm_device_t *dev, unsigned long page)
 {
-       if(page == 0UL) 
+       if(page == 0UL)
                return;
-       
+
        atomic_dec(&virt_to_page(page)->count);
        clear_bit(PG_locked, &virt_to_page(page)->flags);
        wake_up(&virt_to_page(page)->wait);
@@ -304,26 +310,26 @@ static int i810_dma_cleanup(drm_device_t *dev)
 
        if(dev->dev_private) {
                int i;
-               drm_i810_private_t *dev_priv = 
+               drm_i810_private_t *dev_priv =
                        (drm_i810_private_t *) dev->dev_private;
-          
+
                if(dev_priv->ring.virtual_start) {
-                       drm_ioremapfree((void *) dev_priv->ring.virtual_start,
-                                       dev_priv->ring.Size);
+                       DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+                                        dev_priv->ring.Size);
                }
                if(dev_priv->hw_status_page != 0UL) {
                        i810_free_page(dev, dev_priv->hw_status_page);
                        /* Need to rewrite hardware status page */
                        I810_WRITE(0x02080, 0x1ffff000);
                }
-               drm_free(dev->dev_private, sizeof(drm_i810_private_t), 
+               DRM(free)(dev->dev_private, sizeof(drm_i810_private_t),
                         DRM_MEM_DRIVER);
                dev->dev_private = NULL;
 
                for (i = 0; i < dma->buf_count; i++) {
                        drm_buf_t *buf = dma->buflist[ i ];
                        drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-                       drm_ioremapfree(buf_priv->kernel_virtual, buf->total);
+                       DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total);
                }
        }
        return 0;
@@ -340,14 +346,14 @@ static int i810_wait_ring(drm_device_t *dev, int n)
        end = jiffies + (HZ*3);
        while (ring->space < n) {
                int i;
-       
+
                ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
                ring->space = ring->head - (ring->tail+8);
                if (ring->space < 0) ring->space += ring->Size;
-          
+
                if (ring->head != last_head)
                   end = jiffies + (HZ*3);
-         
+
                iters++;
                if((signed)(end - jiffies) <= 0) {
                        DRM_ERROR("space: %d wanted %d\n", ring->space, n);
@@ -358,7 +364,7 @@ static int i810_wait_ring(drm_device_t *dev, int n)
                for (i = 0 ; i < 2000 ; i++) ;
        }
 
-out_wait_ring:   
+out_wait_ring:
        return iters;
 }
 
@@ -366,21 +372,20 @@ static void i810_kernel_lost_context(drm_device_t *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
        drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
-      
+
        ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
        ring->tail = I810_READ(LP_RING + RING_TAIL);
        ring->space = ring->head - (ring->tail+8);
        if (ring->space < 0) ring->space += ring->Size;
 }
 
-static int i810_freelist_init(drm_device_t *dev)
+static int i810_freelist_init(drm_device_t *dev, drm_i810_private_t *dev_priv)
 {
        drm_device_dma_t *dma = dev->dma;
-       drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        int my_idx = 24;
        u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
        int i;
-   
+
        if(dma->buf_count > 1019) {
                /* Not enough space in the status page for the freelist */
                return -EINVAL;
@@ -389,62 +394,82 @@ static int i810_freelist_init(drm_device_t *dev)
        for (i = 0; i < dma->buf_count; i++) {
                drm_buf_t *buf = dma->buflist[ i ];
                drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-          
+
                buf_priv->in_use = hw_status++;
                buf_priv->my_use_idx = my_idx;
                my_idx += 4;
 
                *buf_priv->in_use = I810_BUF_FREE;
 
-               buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 
-                                                      buf->total);
+               buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address,
+                                                       buf->total);
        }
        return 0;
 }
 
-static int i810_dma_initialize(drm_device_t *dev, 
+static int i810_dma_initialize(drm_device_t *dev,
                               drm_i810_private_t *dev_priv,
                               drm_i810_init_t *init)
 {
-       drm_map_t *sarea_map;
+       struct list_head *list;
 
-       dev->dev_private = (void *) dev_priv;
        memset(dev_priv, 0, sizeof(drm_i810_private_t));
 
-       if (init->ring_map_idx >= dev->map_count ||
-           init->buffer_map_idx >= dev->map_count) {
+       list_for_each(list, &dev->maplist->head) {
+               drm_map_list_t *r_list = (drm_map_list_t *)list;
+               if( r_list->map &&
+                   r_list->map->type == _DRM_SHM &&
+                   r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+                       dev_priv->sarea_map = r_list->map;
+                       break;
+               }
+       }
+       if(!dev_priv->sarea_map) {
+               dev->dev_private = (void *)dev_priv;
+               i810_dma_cleanup(dev);
+               DRM_ERROR("can not find sarea!\n");
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
+       if(!dev_priv->mmio_map) {
+               dev->dev_private = (void *)dev_priv;
+               i810_dma_cleanup(dev);
+               DRM_ERROR("can not find mmio map!\n");
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
+       if(!dev_priv->buffer_map) {
+               dev->dev_private = (void *)dev_priv;
                i810_dma_cleanup(dev);
-               DRM_ERROR("ring_map or buffer_map are invalid\n");
+               DRM_ERROR("can not find dma buffer map!\n");
                return -EINVAL;
        }
-   
-       dev_priv->ring_map_idx = init->ring_map_idx;
-       dev_priv->buffer_map_idx = init->buffer_map_idx;
-       sarea_map = dev->maplist[0];
-       dev_priv->sarea_priv = (drm_i810_sarea_t *) 
-               ((u8 *)sarea_map->handle + 
+
+       dev_priv->sarea_priv = (drm_i810_sarea_t *)
+               ((u8 *)dev_priv->sarea_map->handle +
                 init->sarea_priv_offset);
 
        atomic_set(&dev_priv->flush_done, 0);
        init_waitqueue_head(&dev_priv->flush_queue);
-       
+
        dev_priv->ring.Start = init->ring_start;
        dev_priv->ring.End = init->ring_end;
        dev_priv->ring.Size = init->ring_size;
 
-       dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 
-                                                  init->ring_start, 
-                                                  init->ring_size);
+       dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base +
+                                                   init->ring_start,
+                                                   init->ring_size);
 
-       dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
-   
        if (dev_priv->ring.virtual_start == NULL) {
+               dev->dev_private = (void *) dev_priv;
                i810_dma_cleanup(dev);
                DRM_ERROR("can not ioremap virtual address for"
                          " ring buffer\n");
                return -ENOMEM;
        }
 
+       dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+
        dev_priv->w = init->w;
        dev_priv->h = init->h;
        dev_priv->pitch = init->pitch;
@@ -454,28 +479,31 @@ static int i810_dma_initialize(drm_device_t *dev,
        dev_priv->front_di1 = init->front_offset | init->pitch_bits;
        dev_priv->back_di1 = init->back_offset | init->pitch_bits;
        dev_priv->zi1 = init->depth_offset | init->pitch_bits;
-       
-   
+
        /* Program Hardware Status Page */
        dev_priv->hw_status_page = i810_alloc_page(dev);
-       memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
        if(dev_priv->hw_status_page == 0UL) {
+               dev->dev_private = (void *)dev_priv;
                i810_dma_cleanup(dev);
                DRM_ERROR("Can not allocate hardware status page\n");
                return -ENOMEM;
        }
+       memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
        DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
-   
+
        I810_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
        DRM_DEBUG("Enabled hardware status page\n");
-   
+
        /* Now we need to init our freelist */
-       if(i810_freelist_init(dev) != 0) {
+       if(i810_freelist_init(dev, dev_priv) != 0) {
+               dev->dev_private = (void *)dev_priv;
                i810_dma_cleanup(dev);
                DRM_ERROR("Not enough space in the status page for"
                          " the freelist\n");
                return -ENOMEM;
        }
+       dev->dev_private = (void *)dev_priv;
+
        return 0;
 }
 
@@ -487,13 +515,13 @@ int i810_dma_init(struct inode *inode, struct file *filp,
        drm_i810_private_t *dev_priv;
        drm_i810_init_t init;
        int retcode = 0;
-       
+
        if (copy_from_user(&init, (drm_i810_init_t *)arg, sizeof(init)))
                return -EFAULT;
-       
+
        switch(init.func) {
                case I810_INIT_DMA:
-                       dev_priv = drm_alloc(sizeof(drm_i810_private_t), 
+                       dev_priv = DRM(alloc)(sizeof(drm_i810_private_t),
                                             DRM_MEM_DRIVER);
                        if(dev_priv == NULL) return -ENOMEM;
                        retcode = i810_dma_initialize(dev, dev_priv, &init);
@@ -505,7 +533,7 @@ int i810_dma_init(struct inode *inode, struct file *filp,
                        retcode = -EINVAL;
                break;
        }
-   
+
        return retcode;
 }
 
@@ -517,9 +545,9 @@ int i810_dma_init(struct inode *inode, struct file *filp,
  * Use 'volatile' & local var tmp to force the emitted values to be
  * identical to the verified ones.
  */
-static void i810EmitContextVerified( drm_device_t *dev, 
-                                    volatile unsigned int *code ) 
-{      
+static void i810EmitContextVerified( drm_device_t *dev,
+                                    volatile unsigned int *code )
+{
        drm_i810_private_t *dev_priv = dev->dev_private;
        int i, j = 0;
        unsigned int tmp;
@@ -537,22 +565,22 @@ static void i810EmitContextVerified( drm_device_t *dev,
                tmp = code[i];
 
                if ((tmp & (7<<29)) == (3<<29) &&
-                   (tmp & (0x1f<<24)) < (0x1d<<24)) 
+                   (tmp & (0x1f<<24)) < (0x1d<<24))
                {
-                       OUT_RING( tmp ); 
+                       OUT_RING( tmp );
                        j++;
-               } 
+               }
        }
 
-       if (j & 1) 
-               OUT_RING( 0 ); 
+       if (j & 1)
+               OUT_RING( 0 );
 
        ADVANCE_LP_RING();
 }
 
-static void i810EmitTexVerified( drm_device_t *dev, 
-                                volatile unsigned int *code ) 
-{      
+static void i810EmitTexVerified( drm_device_t *dev,
+                                volatile unsigned int *code )
+{
        drm_i810_private_t *dev_priv = dev->dev_private;
        int i, j = 0;
        unsigned int tmp;
@@ -569,15 +597,15 @@ static void i810EmitTexVerified( drm_device_t *dev,
                tmp = code[i];
 
                if ((tmp & (7<<29)) == (3<<29) &&
-                   (tmp & (0x1f<<24)) < (0x1d<<24)) 
+                   (tmp & (0x1f<<24)) < (0x1d<<24))
                {
-                       OUT_RING( tmp ); 
+                       OUT_RING( tmp );
                        j++;
                }
-       } 
-               
-       if (j & 1) 
-               OUT_RING( 0 ); 
+       }
+
+       if (j & 1)
+               OUT_RING( 0 );
 
        ADVANCE_LP_RING();
 }
@@ -585,9 +613,9 @@ static void i810EmitTexVerified( drm_device_t *dev,
 
 /* Need to do some additional checking when setting the dest buffer.
  */
-static void i810EmitDestVerified( drm_device_t *dev, 
-                                 volatile unsigned int *code ) 
-{      
+static void i810EmitDestVerified( drm_device_t *dev,
+                                 volatile unsigned int *code )
+{
        drm_i810_private_t *dev_priv = dev->dev_private;
        unsigned int tmp;
        RING_LOCALS;
@@ -651,9 +679,9 @@ static void i810EmitState( drm_device_t *dev )
 
 
 
-/* need to verify 
+/* need to verify
  */
-static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, 
+static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
                                     unsigned int clear_color,
                                     unsigned int clear_zval )
 {
@@ -684,10 +712,10 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
                    pbox->y2 > dev_priv->h)
                        continue;
 
-               if ( flags & I810_FRONT ) {         
+               if ( flags & I810_FRONT ) {
                        DRM_DEBUG("clear front\n");
-                       BEGIN_LP_RING( 6 );         
-                       OUT_RING( BR00_BITBLT_CLIENT | 
+                       BEGIN_LP_RING( 6 );
+                       OUT_RING( BR00_BITBLT_CLIENT |
                                  BR00_OP_COLOR_BLT | 0x3 );
                        OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
                        OUT_RING( (height << 16) | width );
@@ -699,8 +727,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
 
                if ( flags & I810_BACK ) {
                        DRM_DEBUG("clear back\n");
-                       BEGIN_LP_RING( 6 );         
-                       OUT_RING( BR00_BITBLT_CLIENT | 
+                       BEGIN_LP_RING( 6 );
+                       OUT_RING( BR00_BITBLT_CLIENT |
                                  BR00_OP_COLOR_BLT | 0x3 );
                        OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
                        OUT_RING( (height << 16) | width );
@@ -712,8 +740,8 @@ static void i810_dma_dispatch_clear( drm_device_t *dev, int flags,
 
                if ( flags & I810_DEPTH ) {
                        DRM_DEBUG("clear depth\n");
-                       BEGIN_LP_RING( 6 );         
-                       OUT_RING( BR00_BITBLT_CLIENT | 
+                       BEGIN_LP_RING( 6 );
+                       OUT_RING( BR00_BITBLT_CLIENT |
                                  BR00_OP_COLOR_BLT | 0x3 );
                        OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch );
                        OUT_RING( (height << 16) | width );
@@ -744,7 +772,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
        if (nbox > I810_NR_SAREA_CLIPRECTS)
                nbox = I810_NR_SAREA_CLIPRECTS;
 
-       for (i = 0 ; i < nbox; i++, pbox++) 
+       for (i = 0 ; i < nbox; i++, pbox++)
        {
                unsigned int w = pbox->x2 - pbox->x1;
                unsigned int h = pbox->y2 - pbox->y1;
@@ -756,7 +784,7 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
                    pbox->x2 > dev_priv->w ||
                    pbox->y2 > dev_priv->h)
                        continue;
+
                DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
                          pbox[i].x1, pbox[i].y1,
                          pbox[i].x2, pbox[i].y2);
@@ -766,14 +794,14 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
                OUT_RING( pitch | (0xCC << 16));
                OUT_RING( (h << 16) | (w * cpp));
                OUT_RING( dst );
-               OUT_RING( pitch );      
+               OUT_RING( pitch );
                OUT_RING( start );
                ADVANCE_LP_RING();
        }
 }
 
 
-static void i810_dma_dispatch_vertex(drm_device_t *dev, 
+static void i810_dma_dispatch_vertex(drm_device_t *dev,
                                     drm_buf_t *buf,
                                     int discard,
                                     int used)
@@ -784,30 +812,30 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
        drm_clip_rect_t *box = sarea_priv->boxes;
        int nbox = sarea_priv->nbox;
        unsigned long address = (unsigned long)buf->bus_address;
-       unsigned long start = address - dev->agp->base;     
+       unsigned long start = address - dev->agp->base;
        int i = 0, u;
        RING_LOCALS;
 
        i810_kernel_lost_context(dev);
 
-       if (nbox > I810_NR_SAREA_CLIPRECTS) 
+       if (nbox > I810_NR_SAREA_CLIPRECTS)
                nbox = I810_NR_SAREA_CLIPRECTS;
 
        if (discard) {
-               u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, 
+               u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
                            I810_BUF_HARDWARE);
                if(u != I810_BUF_CLIENT) {
                        DRM_DEBUG("xxxx 2\n");
                }
        }
 
-       if (used > 4*1024) 
+       if (used > 4*1024)
                used = 0;
 
        if (sarea_priv->dirty)
           i810EmitState( dev );
 
-       DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", 
+       DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
                  address, used, nbox);
 
        dev_priv->counter++;
@@ -821,7 +849,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
                *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
                                             sarea_priv->vertex_prim |
                                             ((used/4)-2));
-               
+
                if (used & 4) {
                        *(u32 *)((u32)buf_priv->virtual + used) = 0;
                        used += 4;
@@ -829,26 +857,26 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
 
                i810_unmap_buffer(buf);
        }
-                  
+
        if (used) {
                do {
                        if (i < nbox) {
                                BEGIN_LP_RING(4);
-                               OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | 
+                               OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
                                          SC_ENABLE );
                                OUT_RING( GFX_OP_SCISSOR_INFO );
                                OUT_RING( box[i].x1 | (box[i].y1<<16) );
                                OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
                                ADVANCE_LP_RING();
                        }
-                       
+
                        BEGIN_LP_RING(4);
                        OUT_RING( CMD_OP_BATCH_BUFFER );
                        OUT_RING( start | BB1_PROTECTED );
                        OUT_RING( start + used - 4 );
                        OUT_RING( 0 );
                        ADVANCE_LP_RING();
-                       
+
                } while (++i < nbox);
        }
 
@@ -872,24 +900,25 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
 
 
 /* Interrupts are only for flushing */
-static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
+void i810_dma_service(int irq, void *device, struct pt_regs *regs)
 {
        drm_device_t     *dev = (drm_device_t *)device;
+       drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        u16 temp;
-   
-       atomic_inc(&dev->total_irq);
+
+       atomic_inc(&dev->counts[_DRM_STAT_IRQ]);
        temp = I810_READ16(I810REG_INT_IDENTITY_R);
        temp = temp & ~(0x6000);
-       if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, 
+       if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
                                   temp); /* Clear all interrupts */
        else
           return;
+
        queue_task(&dev->tq, &tq_immediate);
        mark_bh(IMMEDIATE_BH);
 }
 
-static void i810_dma_task_queue(void *device)
+void i810_dma_immediate_bh(void *device)
 {
        drm_device_t *dev = (drm_device_t *) device;
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
@@ -898,129 +927,6 @@ static void i810_dma_task_queue(void *device)
        wake_up_interruptible(&dev_priv->flush_queue);
 }
 
-int i810_irq_install(drm_device_t *dev, int irq)
-{
-       int retcode;
-       u16 temp;
-   
-       if (!irq)     return -EINVAL;
-       
-       down(&dev->struct_sem);
-       if (dev->irq) {
-               up(&dev->struct_sem);
-               return -EBUSY;
-       }
-       dev->irq = irq;
-       up(&dev->struct_sem);
-       
-       DRM_DEBUG(  "Interrupt Install : %d\n", irq);
-       DRM_DEBUG("%d\n", irq);
-
-       dev->context_flag     = 0;
-       dev->interrupt_flag   = 0;
-       dev->dma_flag         = 0;
-       
-       dev->dma->next_buffer = NULL;
-       dev->dma->next_queue  = NULL;
-       dev->dma->this_buffer = NULL;
-
-       INIT_LIST_HEAD(&dev->tq.list);
-       dev->tq.sync          = 0;
-       dev->tq.routine       = i810_dma_task_queue;
-       dev->tq.data          = dev;
-
-                               /* Before installing handler */
-       temp = I810_READ16(I810REG_HWSTAM);
-       temp = temp & 0x6000;
-       I810_WRITE16(I810REG_HWSTAM, temp);
-       
-       temp = I810_READ16(I810REG_INT_MASK_R);
-       temp = temp & 0x6000;
-       I810_WRITE16(I810REG_INT_MASK_R, temp); /* Unmask interrupts */
-       temp = I810_READ16(I810REG_INT_ENABLE_R);
-       temp = temp & 0x6000;
-       I810_WRITE16(I810REG_INT_ENABLE_R, temp); /* Disable all interrupts */
-
-                               /* Install handler */
-       if ((retcode = request_irq(dev->irq,
-                                  i810_dma_service,
-                                  SA_SHIRQ,
-                                  dev->devname,
-                                  dev))) {
-               down(&dev->struct_sem);
-               dev->irq = 0;
-               up(&dev->struct_sem);
-               return retcode;
-       }
-       temp = I810_READ16(I810REG_INT_ENABLE_R);
-       temp = temp & 0x6000;
-       temp = temp | 0x0003;
-       I810_WRITE16(I810REG_INT_ENABLE_R, 
-                    temp); /* Enable bp & user interrupts */
-       return 0;
-}
-
-int i810_irq_uninstall(drm_device_t *dev)
-{
-       int irq;
-       u16 temp;
-
-
-/*     return 0; */
-
-       down(&dev->struct_sem);
-       irq      = dev->irq;
-       dev->irq = 0;
-       up(&dev->struct_sem);
-       
-       if (!irq) return -EINVAL;
-
-       DRM_DEBUG(  "Interrupt UnInstall: %d\n", irq);  
-       DRM_DEBUG("%d\n", irq);
-   
-       temp = I810_READ16(I810REG_INT_IDENTITY_R);
-       temp = temp & ~(0x6000);
-       if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R, 
-                                  temp); /* Clear all interrupts */
-   
-       temp = I810_READ16(I810REG_INT_ENABLE_R);
-       temp = temp & 0x6000;
-       I810_WRITE16(I810REG_INT_ENABLE_R, 
-                    temp);                     /* Disable all interrupts */
-
-       free_irq(irq, dev);
-
-       return 0;
-}
-
-int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_control_t   ctl;
-       int             retcode;
-   
-       DRM_DEBUG(  "i810_control\n");
-
-       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
-               return -EFAULT;
-       
-       switch (ctl.func) {
-       case DRM_INST_HANDLER:
-               if ((retcode = i810_irq_install(dev, ctl.irq)))
-                       return retcode;
-               break;
-       case DRM_UNINST_HANDLER:
-               if ((retcode = i810_irq_uninstall(dev)))
-                       return retcode;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
 static inline void i810_dma_emit_flush(drm_device_t *dev)
 {
        drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1057,11 +963,11 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev)
 /*             wake_up_interruptible(&dev_priv->flush_queue); */
 }
 
-static void i810_dma_quiescent(drm_device_t *dev)
+void i810_dma_quiescent(drm_device_t *dev)
 {
        DECLARE_WAITQUEUE(entry, current);
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
-       unsigned long end;      
+       unsigned long end;
 
        if(dev_priv == NULL) {
                return;
@@ -1069,7 +975,7 @@ static void i810_dma_quiescent(drm_device_t *dev)
        atomic_set(&dev_priv->flush_done, 0);
        add_wait_queue(&dev_priv->flush_queue, &entry);
        end = jiffies + (HZ*3);
-   
+
        for (;;) {
                current->state = TASK_INTERRUPTIBLE;
                i810_dma_quiescent_emit(dev);
@@ -1077,16 +983,16 @@ static void i810_dma_quiescent(drm_device_t *dev)
                if((signed)(end - jiffies) <= 0) {
                        DRM_ERROR("lockup\n");
                        break;
-               }          
+               }
                schedule_timeout(HZ*3);
                if (signal_pending(current)) {
                        break;
                }
        }
-   
+
        current->state = TASK_RUNNING;
        remove_wait_queue(&dev_priv->flush_queue, &entry);
-   
+
        return;
 }
 
@@ -1096,7 +1002,7 @@ static int i810_flush_queue(drm_device_t *dev)
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        drm_device_dma_t *dma = dev->dma;
        unsigned long end;
-       int i, ret = 0;      
+       int i, ret = 0;
 
        if(dev_priv == NULL) {
                return 0;
@@ -1111,14 +1017,14 @@ static int i810_flush_queue(drm_device_t *dev)
                if((signed)(end - jiffies) <= 0) {
                        DRM_ERROR("lockup\n");
                        break;
-               }          
+               }
                schedule_timeout(HZ*3);
                if (signal_pending(current)) {
                        ret = -EINTR; /* Can't restart */
                        break;
                }
        }
-   
+
        current->state = TASK_RUNNING;
        remove_wait_queue(&dev_priv->flush_queue, &entry);
 
@@ -1126,8 +1032,8 @@ static int i810_flush_queue(drm_device_t *dev)
        for (i = 0; i < dma->buf_count; i++) {
                drm_buf_t *buf = dma->buflist[ i ];
                drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-          
-               int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, 
+
+               int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
                                   I810_BUF_FREE);
 
                if (used == I810_BUF_HARDWARE)
@@ -1154,9 +1060,9 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid)
        for (i = 0; i < dma->buf_count; i++) {
                drm_buf_t *buf = dma->buflist[ i ];
                drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-          
+
                if (buf->pid == pid && buf_priv) {
-                       int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, 
+                       int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
                                           I810_BUF_FREE);
 
                        if (used == I810_BUF_CLIENT)
@@ -1167,91 +1073,12 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid)
        }
 }
 
-int i810_lock(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-
-       DECLARE_WAITQUEUE(entry, current);
-       int               ret   = 0;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-   
-       DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                 lock.context, current->pid, dev->lock.hw_lock->lock,
-                 lock.flags);
-
-       if (lock.context < 0) {
-               return -EINVAL;
-       }
-       /* Only one queue:
-        */
-
-       if (!ret) {
-               add_wait_queue(&dev->lock.lock_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!dev->lock.hw_lock) {
-                               /* Device has been unregistered */
-                               ret = -EINTR;
-                               break;
-                       }
-                       if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                         lock.context)) {
-                               dev->lock.pid       = current->pid;
-                               dev->lock.lock_time = jiffies;
-                               atomic_inc(&dev->total_locks);
-                               break;  /* Got lock */
-                       }
-                       
-                               /* Contention */
-                       atomic_inc(&dev->total_sleeps);
-                       DRM_DEBUG("Calling lock schedule\n");
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->lock.lock_queue, &entry);
-       }
-       
-       if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
-               if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                  DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
-                  DRM_DEBUG("fred\n");
-                  i810_dma_quiescent(dev);
-               }
-       }
-       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-       return ret;
-}
-
-int i810_flush_ioctl(struct inode *inode, struct file *filp, 
+int i810_flush_ioctl(struct inode *inode, struct file *filp,
                     unsigned int cmd, unsigned long arg)
 {
        drm_file_t        *priv   = filp->private_data;
        drm_device_t      *dev    = priv->dev;
-   
+
        DRM_DEBUG("i810_flush_ioctl\n");
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_flush_ioctl called without lock held\n");
@@ -1271,8 +1098,8 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
        drm_device_dma_t *dma = dev->dma;
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        u32 *hw_status = (u32 *)dev_priv->hw_status_page;
-       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 
-                                       dev_priv->sarea_priv; 
+       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+                                       dev_priv->sarea_priv;
        drm_i810_vertex_t vertex;
 
        if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
@@ -1288,15 +1115,15 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
 
        if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
 
-       i810_dma_dispatch_vertex( dev, 
-                                 dma->buflist[ vertex.idx ], 
+       i810_dma_dispatch_vertex( dev,
+                                 dma->buflist[ vertex.idx ],
                                  vertex.discard, vertex.used );
 
-       atomic_add(vertex.used, &dma->total_bytes);
-       atomic_inc(&dma->total_dmas);
+       atomic_add(vertex.used, &dev->counts[_DRM_STAT_SECONDARY]);
+       atomic_inc(&dev->counts[_DRM_STAT_DMA]);
        sarea_priv->last_enqueue = dev_priv->counter-1;
        sarea_priv->last_dispatch = (int) hw_status[5];
-   
+
        return 0;
 }
 
@@ -1311,14 +1138,19 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
 
        if (copy_from_user(&clear, (drm_i810_clear_t *)arg, sizeof(clear)))
                return -EFAULT;
-   
+
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_clear_bufs called without lock held\n");
                return -EINVAL;
        }
 
-       i810_dma_dispatch_clear( dev, clear.flags, 
-                                clear.clear_color, 
+       /* GH: Someone's doing nasty things... */
+       if (!dev->dev_private) {
+               return -EINVAL;
+       }
+
+       i810_dma_dispatch_clear( dev, clear.flags,
+                                clear.clear_color,
                                 clear.clear_depth );
        return 0;
 }
@@ -1328,7 +1160,7 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-   
+
        DRM_DEBUG("i810_swap_bufs\n");
 
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
@@ -1347,8 +1179,8 @@ int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_device_t      *dev      = priv->dev;
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        u32 *hw_status = (u32 *)dev_priv->hw_status_page;
-       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 
-                                       dev_priv->sarea_priv; 
+       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+                                       dev_priv->sarea_priv;
 
        sarea_priv->last_dispatch = (int) hw_status[5];
        return 0;
@@ -1363,18 +1195,18 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_i810_dma_t    d;
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        u32 *hw_status = (u32 *)dev_priv->hw_status_page;
-       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 
-                                       dev_priv->sarea_priv; 
+       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+                                       dev_priv->sarea_priv;
 
        DRM_DEBUG("getbuf\n");
        if (copy_from_user(&d, (drm_i810_dma_t *)arg, sizeof(d)))
                return -EFAULT;
-   
+
        if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
                DRM_ERROR("i810_dma called without lock held\n");
                return -EINVAL;
        }
-       
+
        d.granted = 0;
 
        retcode = i810_dma_get_buffer(dev, &d, filp);
@@ -1397,8 +1229,8 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_i810_copy_t   d;
        drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
        u32 *hw_status = (u32 *)dev_priv->hw_status_page;
-       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 
-                                       dev_priv->sarea_priv; 
+       drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+                                       dev_priv->sarea_priv;
        drm_buf_t *buf;
        drm_i810_buf_priv_t *buf_priv;
        drm_device_dma_t *dma = dev->dma;
@@ -1407,20 +1239,17 @@ int i810_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
                DRM_ERROR("i810_dma called without lock held\n");
                return -EINVAL;
        }
-   
+
        if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
                return -EFAULT;
 
-       if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
+        if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
        buf = dma->buflist[ d.idx ];
        buf_priv = buf->dev_private;
        if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
 
-       /* Stopping end users copying their data to the entire kernel
-          is good.. */
-       if (d.used < 0 || d.used > buf->total)
-               return -EINVAL;
-               
+       if(d.used < 0 || d.used > buf->total) return -EINVAL;
+
        if (copy_from_user(buf_priv->virtual, d.address, d.used))
                return -EFAULT;
 
index c5f51c9ad127b90dfd0a4699b437e5015adb058d..5d47adda2c63c702a092d9e22d1b64dead6e2cdf 100644 (file)
@@ -98,8 +98,13 @@ typedef struct _drm_i810_init {
                I810_INIT_DMA = 0x01,
                I810_CLEANUP_DMA = 0x02
        } func;
+#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
        int ring_map_idx;
        int buffer_map_idx;
+#else
+       unsigned int mmio_offset;
+       unsigned int buffers_offset;
+#endif
        int sarea_priv_offset;
        unsigned int ring_start;
        unsigned int ring_end;
index 7152eac3a5eb113b8e33a97bc1b99f8156241b74..a228cb466193ad53924d79907b2f4d1dda8c5bbf 100644 (file)
  * 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
+ * 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>
- *         Jeff Hartmann <jhartmann@valinux.com>
+ * 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>
+ *    Jeff Hartmann <jhartmann@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #include <linux/config.h>
+#include "i810.h"
 #include "drmP.h"
 #include "i810_drv.h"
 
-#define I810_NAME       "i810"
-#define I810_DESC       "Intel I810"
-#define I810_DATE       "20000928"
-#define I810_MAJOR      1
-#define I810_MINOR      1
-#define I810_PATCHLEVEL         0
-
-static drm_device_t          i810_device;
-drm_ctx_t                    i810_res_ctx;
-
-static struct file_operations i810_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#endif
-       open:    i810_open,
-       flush:   drm_flush,
-       release: i810_release,
-       ioctl:   i810_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
-
-static struct miscdevice      i810_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  I810_NAME,
-       fops:  &i810_fops,
-};
-
-static drm_ioctl_desc_t              i810_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]     = { i810_version,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]  = { drm_getunique,  0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]   = { drm_getmagic,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]   = { drm_irq_busid,  0, 1 },
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
 
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]  = { drm_setunique,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]       = { drm_block,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]     = { drm_unblock,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]     = { i810_control,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]  = { drm_authmagic,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]     = { drm_addmap,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]    = { i810_addbufs,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]   = { i810_markbufs,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]   = { i810_infobufs,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]   = { i810_freebufs,  1, 0 },
+#define DRIVER_NAME            "i810"
+#define DRIVER_DESC            "Intel i810"
+#define DRIVER_DATE            "20010616"
 
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]     = { i810_addctx,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]      = { i810_rmctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]     = { i810_modctx,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]     = { i810_getctx,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]  = { i810_switchctx,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]     = { i810_newctx,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]     = { i810_resctx,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]    = { drm_adddraw,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]     = { drm_rmdraw,     1, 1 },
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      0
 
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]        = { i810_lock,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]      = { i810_unlock,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]      = { drm_finish,     1, 0 },
+#define DRIVER_IOCTLS                                                      \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)]   = { i810_dma_init,    1, 1 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex,  1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)]  = { i810_clear_bufs,  1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)]  = { i810_flush_ioctl, 1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage,      1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,      1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,   1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,     1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]  = { drm_agp_enable,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]    = { drm_agp_info,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]   = { drm_agp_alloc,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]    = { drm_agp_free,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]    = { drm_agp_bind,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]  = { drm_agp_unbind,  1, 1 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)]   = { i810_dma_init,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)]  = { i810_clear_bufs, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)]  = { i810_flush_ioctl,1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,     1, 0 },
-};
+#define __HAVE_COUNTERS         4
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+#define __HAVE_COUNTER9         _DRM_STAT_DMA
 
-#define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls)
 
-#ifdef MODULE
-static char                  *i810 = NULL;
-#endif
-
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("Intel I810");
-MODULE_PARM(i810, "s");
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
 #ifndef MODULE
-/* i810_options is called by the kernel to parse command-line options
+/* DRM(options) is called by the kernel to parse command-line options
  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
  * routine, drm_parse_drm.
  */
 
-static int __init i810_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init i810_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("i810=", i810_options);
-#endif
-
-static int i810_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       drm_dma_setup(dev);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-#if DRM_DMA_HISTO
-       memset(&dev->histo, 0, sizeof(dev->histo));
-#endif
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int i810_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       if (dev->irq) i810_irq_uninstall(dev);
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-                               /* Clear AGP information */
-       if (dev->agp) {
-               drm_agp_mem_t *entry;
-               drm_agp_mem_t *nexte;
-
-                               /* Remove AGP resources, but leave dev->agp
-                                   intact until r128_cleanup is called. */
-               for (entry = dev->agp->memory; entry; entry = nexte) {
-                       nexte = entry->next;
-                       if (entry->bound) drm_unbind_agp(entry->memory);
-                       drm_free_agp(entry->memory, entry->pages);
-                       drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               }
-               dev->agp->memory = NULL;
-
-               if (dev->agp->acquired) _drm_agp_release();
-
-               dev->agp->acquired = 0;
-               dev->agp->enabled  = 0;
-       }
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
-#endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       if (dev->queuelist) {
-               for (i = 0; i < dev->queue_count; i++) {
-                       drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
-                       if (dev->queuelist[i]) {
-                               drm_free(dev->queuelist[i],
-                                        sizeof(*dev->queuelist[0]),
-                                        DRM_MEM_QUEUES);
-                               dev->queuelist[i] = NULL;
-                       }
-               }
-               drm_free(dev->queuelist,
-                        dev->queue_slots * sizeof(*dev->queuelist),
-                        DRM_MEM_QUEUES);
-               dev->queuelist   = NULL;
-       }
-
-       drm_dma_takedown(dev);
-
-       dev->queue_count     = 0;
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-/* i810_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init i810_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &i810_device;
-
-       DRM_DEBUG("\n");
-
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
-
-#ifdef MODULE
-       drm_parse_options(i810);
-#endif
-       DRM_DEBUG("doing misc_register\n");
-       if ((retcode = misc_register(&i810_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", I810_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, i810_misc.minor);
-       dev->name   = I810_NAME;
-
-       DRM_DEBUG("doing mem init\n");
-       drm_mem_init();
-       DRM_DEBUG("doing proc init\n");
-       drm_proc_init(dev);
-       DRM_DEBUG("doing agp init\n");
-       dev->agp    = drm_agp_init();
-       if(dev->agp == NULL) {
-               DRM_INFO("The i810 drm module requires the agpgart module"
-                        " to function correctly\nPlease load the agpgart"
-                        " module before you load the i810 module\n");
-               drm_proc_cleanup();
-               misc_deregister(&i810_misc);
-               i810_takedown(dev);
-               return -ENOMEM;
-       }
-       DRM_DEBUG("doing ctxbitmap init\n");
-       if((retcode = drm_ctxbitmap_init(dev))) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               drm_proc_cleanup();
-               misc_deregister(&i810_misc);
-               i810_takedown(dev);
-               return retcode;
-       }
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-                I810_NAME,
-                I810_MAJOR,
-                I810_MINOR,
-                I810_PATCHLEVEL,
-                I810_DATE,
-                i810_misc.minor);
-
-       return 0;
-}
-
-/* i810_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit i810_cleanup(void)
-{
-       drm_device_t          *dev = &i810_device;
-
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&i810_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       drm_ctxbitmap_cleanup(dev);
-       i810_takedown(dev);
-       if (dev->agp) {
-               drm_agp_uninit();
-               drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-               dev->agp = NULL;
-       }
-}
-
-module_init(i810_init);
-module_exit(i810_cleanup);
-
-
-int i810_version(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                \
-       len = strlen(value);                                 \
-       if (len > name##_len) len = name##_len;              \
-       name##_len = strlen(value);                          \
-       if (len && name) {                                   \
-               if (copy_to_user(name, value, len))          \
-                       return -EFAULT;                      \
-       }
-
-       version.version_major      = I810_MAJOR;
-       version.version_minor      = I810_MINOR;
-       version.version_patchlevel = I810_PATCHLEVEL;
-
-       DRM_COPY(version.name, I810_NAME);
-       DRM_COPY(version.date, I810_DATE);
-       DRM_COPY(version.desc, I810_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int i810_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &i810_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return i810_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-       return retcode;
-}
-
-int i810_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev    = priv->dev;
-       DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
-                 current->pid, dev->device, dev->open_count);
-
-       if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
-           && dev->lock.pid == current->pid) {
-               i810_reclaim_buffers(dev, priv->pid);
-               DRM_ERROR("Process %d dead, freeing lock for context %d\n",
-                         current->pid,
-                         _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-               drm_lock_free(dev,
-                             &dev->lock.hw_lock->lock,
-                             _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
-                               /* FIXME: may require heavy-handed reset of
-                                   hardware at this point, possibly
-                                   processed via a callback to the X
-                                   server. */
-       } else if (dev->lock.hw_lock) {
-               /* The lock is required to reclaim buffers */
-               DECLARE_WAITQUEUE(entry, current);
-               add_wait_queue(&dev->lock.lock_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!dev->lock.hw_lock) {
-                               /* Device has been unregistered */
-                               retcode = -EINTR;
-                               break;
-                       }
-                       if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                         DRM_KERNEL_CONTEXT)) {
-                               dev->lock.pid       = priv->pid;
-                               dev->lock.lock_time = jiffies;
-                               atomic_inc(&dev->total_locks);
-                               break;  /* Got lock */
-                       }
-                               /* Contention */
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               retcode = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->lock.lock_queue, &entry);
-               if(!retcode) {
-                       i810_reclaim_buffers(dev, priv->pid);
-                       drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                     DRM_KERNEL_CONTEXT);
-               }
-       }
-       drm_fasync(-1, filp, 0);
-
-       down(&dev->struct_sem);
-       if (priv->prev) priv->prev->next = priv->next;
-       else            dev->file_first  = priv->next;
-       if (priv->next) priv->next->prev = priv->prev;
-       else            dev->file_last   = priv->prev;
-       up(&dev->struct_sem);
-
-       drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-#if LINUX_VERSION_CODE < 0x020333
-       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-       atomic_inc(&dev->total_close);
-       spin_lock(&dev->count_lock);
-       if (!--dev->open_count) {
-               if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                       DRM_ERROR("Device busy: %d %d\n",
-                                 atomic_read(&dev->ioctl_count),
-                                 dev->blocked);
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return -EBUSY;
-               }
-               spin_unlock(&dev->count_lock);
-               unlock_kernel();
-               return i810_takedown(dev);
-       }
-       spin_unlock(&dev->count_lock);
-       unlock_kernel();
-       return retcode;
-}
-
-/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-
-int i810_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= I810_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &i810_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-int i810_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-       if (!dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
-#if DRM_DMA_HISTOGRAM
-       atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
-                                                      - dev->lck_start)]);
+__setup( DRIVER_NAME "=", i810_options );
 #endif
 
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_lists.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
index 1c957401717af8df70c1bbea5b9704c9dc726572..e1b17148e9412837cd2952f093a9eb12fbf0259c 100644 (file)
  * 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
@@ -54,11 +54,12 @@ typedef struct _drm_i810_ring_buffer{
 } drm_i810_ring_buffer_t;
 
 typedef struct drm_i810_private {
-       int ring_map_idx;
-       int buffer_map_idx;
+       drm_map_t *sarea_map;
+       drm_map_t *buffer_map;
+       drm_map_t *mmio_map;
 
-       drm_i810_ring_buffer_t ring;
        drm_i810_sarea_t *sarea_priv;
+       drm_i810_ring_buffer_t ring;
 
        unsigned long hw_status_page;
        unsigned long counter;
@@ -67,78 +68,33 @@ typedef struct drm_i810_private {
        wait_queue_head_t flush_queue;  /* Processes waiting until flush    */
        drm_buf_t *mmap_buffer;
 
-       
+
        u32 front_di1, back_di1, zi1;
-       
+
        int back_offset;
        int depth_offset;
        int w, h;
        int pitch;
 } drm_i810_private_t;
 
-                               /* i810_drv.c */
-extern int  i810_version(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  i810_open(struct inode *inode, struct file *filp);
-extern int  i810_release(struct inode *inode, struct file *filp);
-extern int  i810_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  i810_unlock(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-
                                /* i810_dma.c */
 extern int  i810_dma_schedule(drm_device_t *dev, int locked);
 extern int  i810_getbuf(struct inode *inode, struct file *filp,
                        unsigned int cmd, unsigned long arg);
-extern int  i810_irq_install(drm_device_t *dev, int irq);
-extern int  i810_irq_uninstall(drm_device_t *dev);
-extern int  i810_control(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  i810_lock(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
 extern int  i810_dma_init(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg);
 extern int  i810_flush_ioctl(struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg);
 extern void i810_reclaim_buffers(drm_device_t *dev, pid_t pid);
-extern int  i810_getage(struct inode *inode, struct file *filp, unsigned int cmd,
-                       unsigned long arg);
-extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
-extern int i810_copybuf(struct inode *inode, struct file *filp, 
+extern int  i810_getage(struct inode *inode, struct file *filp,
                        unsigned int cmd, unsigned long arg);
-extern int i810_docopy(struct inode *inode, struct file *filp, 
-                      unsigned int cmd, unsigned long arg);
-
-                               /* i810_bufs.c */
-extern int  i810_addbufs(struct inode *inode, struct file *filp, 
+extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
+extern int i810_copybuf(struct inode *inode, struct file *filp,
                        unsigned int cmd, unsigned long arg);
-extern int  i810_infobufs(struct inode *inode, struct file *filp, 
-                        unsigned int cmd, unsigned long arg);
-extern int  i810_markbufs(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-extern int  i810_freebufs(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-extern int  i810_addmap(struct inode *inode, struct file *filp,
+extern int i810_docopy(struct inode *inode, struct file *filp,
                       unsigned int cmd, unsigned long arg);
 
-                               /* i810_context.c */
-extern int  i810_resctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  i810_addctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  i810_modctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  i810_getctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  i810_switchctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  i810_newctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  i810_rmctx(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-
-extern int  i810_context_switch(drm_device_t *dev, int old, int new);
-extern int  i810_context_switch_complete(drm_device_t *dev, int new);
+extern void i810_dma_quiescent(drm_device_t *dev);
 
 #define I810_VERBOSE 0
 
@@ -152,6 +108,18 @@ int i810_swap_bufs(struct inode *inode, struct file *filp,
 int i810_clear_bufs(struct inode *inode, struct file *filp,
                    unsigned int cmd, unsigned long arg);
 
+
+#define I810_BASE(reg)         ((unsigned long) \
+                               dev_priv->mmio_map->handle)
+#define I810_ADDR(reg)         (I810_BASE(reg) + reg)
+#define I810_DEREF(reg)                *(__volatile__ int *)I810_ADDR(reg)
+#define I810_READ(reg)         I810_DEREF(reg)
+#define I810_WRITE(reg,val)    do { I810_DEREF(reg) = val; } while (0)
+#define I810_DEREF16(reg)      *(__volatile__ u16 *)I810_ADDR(reg)
+#define I810_READ16(reg)       I810_DEREF16(reg)
+#define I810_WRITE16(reg,val)  do { I810_DEREF16(reg) = val; } while (0)
+
+
 #define GFX_OP_USER_INTERRUPT          ((0<<29)|(2<<23))
 #define GFX_OP_BREAKPOINT_INTERRUPT    ((0<<29)|(1<<23))
 #define CMD_REPORT_HEAD                        (7<<23)
@@ -184,7 +152,7 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
 #define RING_START                     0x08
 #define START_ADDR             0x00FFFFF8
 #define RING_LEN                       0x0C
-#define RING_NR_PAGES          0x000FF000 
+#define RING_NR_PAGES          0x000FF000
 #define RING_REPORT_MASK       0x00000006
 #define RING_REPORT_64K        0x00000002
 #define RING_REPORT_128K       0x00000004
@@ -222,4 +190,3 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
 
 
 #endif
-
diff --git a/drivers/char/drm/init.c b/drivers/char/drm/init.c
deleted file mode 100644 (file)
index 8de3dac..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* init.c -- Setup/Cleanup for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-int                          drm_flags         = 0;
-
-/* drm_parse_option parses a single option.  See description for
-   drm_parse_options for details. */
-
-static void drm_parse_option(char *s)
-{
-       char *c, *r;
-       
-       DRM_DEBUG("\"%s\"\n", s);
-       if (!s || !*s) return;
-       for (c = s; *c && *c != ':'; c++); /* find : or \0 */
-       if (*c) r = c + 1; else r = NULL;  /* remember remainder */
-       *c = '\0';                         /* terminate */
-       if (!strcmp(s, "noctx")) {
-               drm_flags |= DRM_FLAG_NOCTX;
-               DRM_INFO("Server-mediated context switching OFF\n");
-               return;
-       }
-       if (!strcmp(s, "debug")) {
-               drm_flags |= DRM_FLAG_DEBUG;
-               DRM_INFO("Debug messages ON\n");
-               return;
-       }
-       DRM_ERROR("\"%s\" is not a valid option\n", s);
-       return;
-}
-
-/* drm_parse_options parse the insmod "drm=" options, or the command-line
- * options passed to the kernel via LILO.  The grammar of the format is as
- * follows:
- *
- * drm         ::= 'drm=' option_list
- * option_list ::= option [ ';' option_list ]
- * option      ::= 'device:' major
- *             |   'debug' 
- *             |   'noctx'
- * major       ::= INTEGER
- *
- * Note that 's' contains option_list without the 'drm=' part.
- *
- * device=major,minor specifies the device number used for /dev/drm
- *       if major == 0 then the misc device is used
- *       if major == 0 and minor == 0 then dynamic misc allocation is used
- * debug=on specifies that debugging messages will be printk'd
- * debug=trace specifies that each function call will be logged via printk
- * debug=off turns off all debugging options
- *
- */
-
-void drm_parse_options(char *s)
-{
-       char *h, *t, *n;
-       
-       DRM_DEBUG("\"%s\"\n", s ?: "");
-       if (!s || !*s) return;
-
-       for (h = t = n = s; h && *h; h = n) {
-               for (; *t && *t != ';'; t++);          /* find ; or \0 */
-               if (*t) n = t + 1; else n = NULL;      /* remember next */
-               *t = '\0';                             /* terminate */
-               drm_parse_option(h);                   /* parse */
-       }
-}
-
-/* drm_cpu_valid returns non-zero if the DRI will run on this CPU, and 0
- * otherwise. */
-
-int drm_cpu_valid(void)
-{
-#if defined(__i386__)
-       if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
-#endif
-#if defined(__sparc__) && !defined(__sparc_v9__)
-       if (1)
-               return 0; /* No cmpxchg before v9 sparc. */
-#endif
-       return 1;
-}
diff --git a/drivers/char/drm/ioctl.c b/drivers/char/drm/ioctl.c
deleted file mode 100644 (file)
index 6c038ad..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* ioctl.c -- IOCTL processing for DRM -*- linux-c -*-
- * Created: Fri Jan  8 09:01:26 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-int drm_irq_busid(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_irq_busid_t p;
-       struct pci_dev  *dev;
-
-       if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p)))
-               return -EFAULT;
-       dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
-       if (dev) p.irq = dev->irq;
-       else     p.irq = 0;
-       DRM_DEBUG("%d:%d:%d => IRQ %d\n",
-                 p.busnum, p.devnum, p.funcnum, p.irq);
-       if (copy_to_user((drm_irq_busid_t *)arg, &p, sizeof(p)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_getunique(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_unique_t     u;
-
-       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
-               return -EFAULT;
-       if (u.unique_len >= dev->unique_len) {
-               if (copy_to_user(u.unique, dev->unique, dev->unique_len))
-                       return -EFAULT;
-       }
-       u.unique_len = dev->unique_len;
-       if (copy_to_user((drm_unique_t *)arg, &u, sizeof(u)))
-               return -EFAULT;
-       return 0;
-}
-
-int drm_setunique(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_unique_t     u;
-
-       if (dev->unique_len || dev->unique)
-               return -EBUSY;
-
-       if (copy_from_user(&u, (drm_unique_t *)arg, sizeof(u)))
-               return -EFAULT;
-
-       if (!u.unique_len || u.unique_len > 1024)
-               return -EINVAL;
-       
-       dev->unique_len = u.unique_len;
-       dev->unique     = drm_alloc(u.unique_len + 1, DRM_MEM_DRIVER);
-       if (copy_from_user(dev->unique, u.unique, dev->unique_len))
-               return -EFAULT;
-       dev->unique[dev->unique_len] = '\0';
-
-       dev->devname = drm_alloc(strlen(dev->name) + strlen(dev->unique) + 2,
-                                DRM_MEM_DRIVER);
-       sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
-
-       return 0;
-}
diff --git a/drivers/char/drm/lists.c b/drivers/char/drm/lists.c
deleted file mode 100644 (file)
index 60e66b8..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* lists.c -- Buffer list handling routines -*- linux-c -*-
- * Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-int drm_waitlist_create(drm_waitlist_t *bl, int count)
-{
-       if (bl->count) return -EINVAL;
-       
-       bl->count      = count;
-       bl->bufs       = drm_alloc((bl->count + 2) * sizeof(*bl->bufs),
-                                  DRM_MEM_BUFLISTS);
-       bl->rp         = bl->bufs;
-       bl->wp         = bl->bufs;
-       bl->end        = &bl->bufs[bl->count+1];
-       bl->write_lock = SPIN_LOCK_UNLOCKED;
-       bl->read_lock  = SPIN_LOCK_UNLOCKED;
-       return 0;
-}
-
-int drm_waitlist_destroy(drm_waitlist_t *bl)
-{
-       if (bl->rp != bl->wp) return -EINVAL;
-       if (bl->bufs) drm_free(bl->bufs,
-                              (bl->count + 2) * sizeof(*bl->bufs),
-                              DRM_MEM_BUFLISTS);
-       bl->count = 0;
-       bl->bufs  = NULL;
-       bl->rp    = NULL;
-       bl->wp    = NULL;
-       bl->end   = NULL;
-       return 0;
-}
-
-int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf)
-{                                                      
-       int           left;
-       unsigned long flags;
-
-       left = DRM_LEFTCOUNT(bl);
-       if (!left) {
-               DRM_ERROR("Overflow while adding buffer %d from pid %d\n",
-                         buf->idx, buf->pid);
-               return -EINVAL;
-       }
-#if DRM_DMA_HISTOGRAM
-       buf->time_queued = get_cycles();
-#endif
-       buf->list        = DRM_LIST_WAIT;
-       
-       spin_lock_irqsave(&bl->write_lock, flags);
-       *bl->wp = buf;
-       if (++bl->wp >= bl->end) bl->wp = bl->bufs;
-       spin_unlock_irqrestore(&bl->write_lock, flags);
-       
-       return 0;
-}
-
-drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl)
-{
-       drm_buf_t     *buf;
-       unsigned long flags;
-
-       spin_lock_irqsave(&bl->read_lock, flags);
-       buf = *bl->rp;
-       if (bl->rp == bl->wp) {
-               spin_unlock_irqrestore(&bl->read_lock, flags);
-               return NULL;
-       }                                    
-       if (++bl->rp >= bl->end) bl->rp = bl->bufs;
-       spin_unlock_irqrestore(&bl->read_lock, flags);
-       
-       return buf;
-}
-
-int drm_freelist_create(drm_freelist_t *bl, int count)
-{
-       atomic_set(&bl->count, 0);
-       bl->next      = NULL;
-       init_waitqueue_head(&bl->waiting);
-       bl->low_mark  = 0;
-       bl->high_mark = 0;
-       atomic_set(&bl->wfh,   0);
-       bl->lock      = SPIN_LOCK_UNLOCKED;
-       ++bl->initialized;
-       return 0;
-}
-
-int drm_freelist_destroy(drm_freelist_t *bl)
-{
-       atomic_set(&bl->count, 0);
-       bl->next = NULL;
-       return 0;
-}
-
-int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
-{
-       drm_device_dma_t *dma  = dev->dma;
-
-       if (!dma) {
-               DRM_ERROR("No DMA support\n");
-               return 1;
-       }
-
-       if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) {
-               DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
-                         buf->idx, buf->waiting, buf->pending, buf->list);
-       }
-       if (!bl) return 1;
-#if DRM_DMA_HISTOGRAM
-       buf->time_freed = get_cycles();
-       drm_histogram_compute(dev, buf);
-#endif
-       buf->list       = DRM_LIST_FREE;
-       
-       spin_lock(&bl->lock);
-       buf->next       = bl->next;
-       bl->next        = buf;
-       spin_unlock(&bl->lock);
-       
-       atomic_inc(&bl->count);
-       if (atomic_read(&bl->count) > dma->buf_count) {
-               DRM_ERROR("%d of %d buffers free after addition of %d\n",
-                         atomic_read(&bl->count), dma->buf_count, buf->idx);
-               return 1;
-       }
-                               /* Check for high water mark */
-       if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
-               atomic_set(&bl->wfh, 0);
-               wake_up_interruptible(&bl->waiting);
-       }
-       return 0;
-}
-
-static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
-{
-       drm_buf_t         *buf;
-
-       if (!bl) return NULL;
-       
-                               /* Get buffer */
-       spin_lock(&bl->lock);
-       if (!bl->next) {
-               spin_unlock(&bl->lock);
-               return NULL;
-       }
-       buf       = bl->next;
-       bl->next  = bl->next->next;
-       spin_unlock(&bl->lock);
-       
-       atomic_dec(&bl->count);
-       buf->next = NULL;
-       buf->list = DRM_LIST_NONE;
-       if (buf->waiting || buf->pending) {
-               DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
-                         buf->idx, buf->waiting, buf->pending, buf->list);
-       }
-       
-       return buf;
-}
-
-drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
-{
-       drm_buf_t         *buf  = NULL;
-       DECLARE_WAITQUEUE(entry, current);
-
-       if (!bl || !bl->initialized) return NULL;
-       
-                               /* Check for low water mark */
-       if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
-               atomic_set(&bl->wfh, 1);
-       if (atomic_read(&bl->wfh)) {
-               if (block) {
-                       add_wait_queue(&bl->waiting, &entry);
-                       for (;;) {
-                               current->state = TASK_INTERRUPTIBLE;
-                               if (!atomic_read(&bl->wfh)
-                                   && (buf = drm_freelist_try(bl))) break;
-                               schedule();
-                               if (signal_pending(current)) break;
-                       }
-                       current->state = TASK_RUNNING;
-                       remove_wait_queue(&bl->waiting, &entry);
-               }
-               return buf;
-       }
-               
-       return drm_freelist_try(bl);
-}
diff --git a/drivers/char/drm/lock.c b/drivers/char/drm/lock.c
deleted file mode 100644 (file)
index 90d2f13..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-/* lock.c -- IOCTLs for locking -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-int drm_block(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
-{
-       DRM_DEBUG("\n");
-       return 0;
-}
-
-int drm_unblock(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       DRM_DEBUG("\n");
-       return 0;
-}
-
-int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
-{
-       unsigned int old, new, prev;
-
-       do {
-               old = *lock;
-               if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
-               else                      new = context | _DRM_LOCK_HELD;
-               prev = cmpxchg(lock, old, new);
-       } while (prev != old);
-       if (_DRM_LOCKING_CONTEXT(old) == context) {
-               if (old & _DRM_LOCK_HELD) {
-                       if (context != DRM_KERNEL_CONTEXT) {
-                               DRM_ERROR("%d holds heavyweight lock\n",
-                                         context);
-                       }
-                       return 0;
-               }
-       }
-       if (new == (context | _DRM_LOCK_HELD)) {
-                               /* Have lock */
-               return 1;
-       }
-       return 0;
-}
-
-/* This takes a lock forcibly and hands it to context. Should ONLY be used
-   inside *_unlock to give lock to kernel before calling *_dma_schedule. */
-int drm_lock_transfer(drm_device_t *dev,
-                     __volatile__ unsigned int *lock, unsigned int context)
-{
-       unsigned int old, new, prev;
-
-       dev->lock.pid = 0;
-       do {
-               old  = *lock;
-               new  = context | _DRM_LOCK_HELD;
-               prev = cmpxchg(lock, old, new);
-       } while (prev != old);
-       return 1;
-}
-
-int drm_lock_free(drm_device_t *dev,
-                 __volatile__ unsigned int *lock, unsigned int context)
-{
-       unsigned int old, new, prev;
-       pid_t        pid = dev->lock.pid;
-
-       dev->lock.pid = 0;
-       do {
-               old  = *lock;
-               new  = 0;
-               prev = cmpxchg(lock, old, new);
-       } while (prev != old);
-       if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
-               DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
-                         context,
-                         _DRM_LOCKING_CONTEXT(old),
-                         pid);
-               return 1;
-       }
-       wake_up_interruptible(&dev->lock.lock_queue);
-       return 0;
-}
-
-static int drm_flush_queue(drm_device_t *dev, int context)
-{
-       DECLARE_WAITQUEUE(entry, current);
-       int               ret   = 0;
-       drm_queue_t       *q    = dev->queuelist[context];
-       
-       DRM_DEBUG("\n");
-       
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) > 1) {
-               atomic_inc(&q->block_write);
-               add_wait_queue(&q->flush_queue, &entry);
-               atomic_inc(&q->block_count);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!DRM_BUFCOUNT(&q->waitlist)) break;
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -EINTR; /* Can't restart */
-                               break;
-                       }
-               }
-               atomic_dec(&q->block_count);
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&q->flush_queue, &entry);
-       }
-       atomic_dec(&q->use_count);
-       atomic_inc(&q->total_flushed);
-               
-                               /* NOTE: block_write is still incremented!
-                                  Use drm_flush_unlock_queue to decrement. */
-       return ret;
-}
-
-static int drm_flush_unblock_queue(drm_device_t *dev, int context)
-{
-       drm_queue_t       *q    = dev->queuelist[context];
-       
-       DRM_DEBUG("\n");
-       
-       atomic_inc(&q->use_count);
-       if (atomic_read(&q->use_count) > 1) {
-               if (atomic_read(&q->block_write)) {
-                       atomic_dec(&q->block_write);
-                       wake_up_interruptible(&q->write_queue);
-               }
-       }
-       atomic_dec(&q->use_count);
-       return 0;
-}
-
-int drm_flush_block_and_flush(drm_device_t *dev, int context,
-                             drm_lock_flags_t flags)
-{
-       int ret = 0;
-       int i;
-       
-       DRM_DEBUG("\n");
-       
-       if (flags & _DRM_LOCK_FLUSH) {
-               ret = drm_flush_queue(dev, DRM_KERNEL_CONTEXT);
-               if (!ret) ret = drm_flush_queue(dev, context);
-       }
-       if (flags & _DRM_LOCK_FLUSH_ALL) {
-               for (i = 0; !ret && i < dev->queue_count; i++) {
-                       ret = drm_flush_queue(dev, i);
-               }
-       }
-       return ret;
-}
-
-int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags)
-{
-       int ret = 0;
-       int i;
-       
-       DRM_DEBUG("\n");
-       
-       if (flags & _DRM_LOCK_FLUSH) {
-               ret = drm_flush_unblock_queue(dev, DRM_KERNEL_CONTEXT);
-               if (!ret) ret = drm_flush_unblock_queue(dev, context);
-       }
-       if (flags & _DRM_LOCK_FLUSH_ALL) {
-               for (i = 0; !ret && i < dev->queue_count; i++) {
-                       ret = drm_flush_unblock_queue(dev, i);
-               }
-       }
-               
-       return ret;
-}
-
-int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       int               ret     = 0;
-       drm_lock_t        lock;
-
-       DRM_DEBUG("\n");
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-       ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
-       drm_flush_unblock(dev, lock.context, lock.flags);
-       return ret;
-}
-
-/* If we get here, it means that the process has called DRM_IOCTL_LOCK
-   without calling DRM_IOCTL_UNLOCK.
-   
-   If the lock is not held, then let the signal proceed as usual.
-   
-   If the lock is held, then set the contended flag and keep the signal
-   blocked.
-   
-
-   Return 1 if the signal should be delivered normally.
-   Return 0 if the signal should be blocked.  */
-
-int drm_notifier(void *priv)
-{
-       drm_sigdata_t *s = (drm_sigdata_t *)priv;
-       unsigned int  old, new, prev;
-
-
-                               /* Allow signal delivery if lock isn't held */
-       if (!_DRM_LOCK_IS_HELD(s->lock->lock)
-           || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
-       
-                               /* Otherwise, set flag to force call to
-                                   drmUnlock */
-       do {
-               old  = s->lock->lock;
-               new  = old | _DRM_LOCK_CONT;
-               prev = cmpxchg(&s->lock->lock, old, new);
-       } while (prev != old);
-       return 0;
-}
diff --git a/drivers/char/drm/memory.c b/drivers/char/drm/memory.c
deleted file mode 100644 (file)
index 261fb34..0000000
+++ /dev/null
@@ -1,448 +0,0 @@
-/* memory.c -- Memory management wrappers for DRM -*- linux-c -*-
- * Created: Thu Feb  4 14:00:34 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include <linux/config.h>
-#include "drmP.h"
-#include <linux/wrapper.h>
-
-typedef struct drm_mem_stats {
-       const char        *name;
-       int               succeed_count;
-       int               free_count;
-       int               fail_count;
-       unsigned long     bytes_allocated;
-       unsigned long     bytes_freed;
-} drm_mem_stats_t;
-
-static spinlock_t        drm_mem_lock      = SPIN_LOCK_UNLOCKED;
-static unsigned long     drm_ram_available = 0; /* In pages */
-static unsigned long     drm_ram_used      = 0;
-static drm_mem_stats_t   drm_mem_stats[]   = {
-       [DRM_MEM_DMA]       = { "dmabufs"  },
-       [DRM_MEM_SAREA]     = { "sareas"   },
-       [DRM_MEM_DRIVER]    = { "driver"   },
-       [DRM_MEM_MAGIC]     = { "magic"    },
-       [DRM_MEM_IOCTLS]    = { "ioctltab" },
-       [DRM_MEM_MAPS]      = { "maplist"  },
-       [DRM_MEM_VMAS]      = { "vmalist"  },
-       [DRM_MEM_BUFS]      = { "buflist"  },
-       [DRM_MEM_SEGS]      = { "seglist"  },
-       [DRM_MEM_PAGES]     = { "pagelist" },
-       [DRM_MEM_FILES]     = { "files"    },
-       [DRM_MEM_QUEUES]    = { "queues"   },
-       [DRM_MEM_CMDS]      = { "commands" },
-       [DRM_MEM_MAPPINGS]  = { "mappings" },
-       [DRM_MEM_BUFLISTS]  = { "buflists" },
-       [DRM_MEM_AGPLISTS]  = { "agplist"  },
-       [DRM_MEM_TOTALAGP]  = { "totalagp" },
-       [DRM_MEM_BOUNDAGP]  = { "boundagp" },
-       [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
-       { NULL, 0, }            /* Last entry must be null */
-};
-
-void drm_mem_init(void)
-{
-       drm_mem_stats_t *mem;
-       struct sysinfo  si;
-       
-       for (mem = drm_mem_stats; mem->name; ++mem) {
-               mem->succeed_count   = 0;
-               mem->free_count      = 0;
-               mem->fail_count      = 0;
-               mem->bytes_allocated = 0;
-               mem->bytes_freed     = 0;
-       }
-       
-       si_meminfo(&si);
-#if LINUX_VERSION_CODE < 0x020317
-                               /* Changed to page count in 2.3.23 */
-       drm_ram_available = si.totalram >> PAGE_SHIFT;
-#else
-       drm_ram_available = si.totalram;
-#endif
-       drm_ram_used      = 0;
-}
-
-/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
-
-static int _drm_mem_info(char *buf, char **start, off_t offset, int len,
-                        int *eof, void *data)
-{
-       drm_mem_stats_t *pt;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT("                  total counts                  "
-                      " |    outstanding  \n");
-       DRM_PROC_PRINT("type       alloc freed fail     bytes      freed"
-                      " | allocs      bytes\n\n");
-       DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
-                      "system", 0, 0, 0,
-                      drm_ram_available << (PAGE_SHIFT - 10));
-       DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
-                      "locked", 0, 0, 0, drm_ram_used >> 10);
-       DRM_PROC_PRINT("\n");
-       for (pt = drm_mem_stats; pt->name; pt++) {
-               DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
-                              pt->name,
-                              pt->succeed_count,
-                              pt->free_count,
-                              pt->fail_count,
-                              pt->bytes_allocated,
-                              pt->bytes_freed,
-                              pt->succeed_count - pt->free_count,
-                              (long)pt->bytes_allocated
-                              - (long)pt->bytes_freed);
-       }
-       
-       return len;
-}
-
-int drm_mem_info(char *buf, char **start, off_t offset, int len,
-                int *eof, void *data)
-{
-       int ret;
-       
-       spin_lock(&drm_mem_lock);
-       ret = _drm_mem_info(buf, start, offset, len, eof, data);
-       spin_unlock(&drm_mem_lock);
-       return ret;
-}
-
-void *drm_alloc(size_t size, int area)
-{
-       void *pt;
-       
-       if (!size) {
-               DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
-               return NULL;
-       }
-       
-       if (!(pt = kmalloc(size, GFP_KERNEL))) {
-               spin_lock(&drm_mem_lock);
-               ++drm_mem_stats[area].fail_count;
-               spin_unlock(&drm_mem_lock);
-               return NULL;
-       }
-       spin_lock(&drm_mem_lock);
-       ++drm_mem_stats[area].succeed_count;
-       drm_mem_stats[area].bytes_allocated += size;
-       spin_unlock(&drm_mem_lock);
-       return pt;
-}
-
-void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
-{
-       void *pt;
-       
-       if (!(pt = drm_alloc(size, area))) return NULL;
-       if (oldpt && oldsize) {
-               memcpy(pt, oldpt, oldsize);
-               drm_free(oldpt, oldsize, area);
-       }
-       return pt;
-}
-
-char *drm_strdup(const char *s, int area)
-{
-       char *pt;
-       int      length = s ? strlen(s) : 0;
-       
-       if (!(pt = drm_alloc(length+1, area))) return NULL;
-       strcpy(pt, s);
-       return pt;
-}
-
-void drm_strfree(const char *s, int area)
-{
-       unsigned int size;
-       
-       if (!s) return;
-       
-       size = 1 + (s ? strlen(s) : 0);
-       drm_free((void *)s, size, area);
-}
-
-void drm_free(void *pt, size_t size, int area)
-{
-       int alloc_count;
-       int free_count;
-       
-       if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
-       else     kfree(pt);
-       spin_lock(&drm_mem_lock);
-       drm_mem_stats[area].bytes_freed += size;
-       free_count  = ++drm_mem_stats[area].free_count;
-       alloc_count =   drm_mem_stats[area].succeed_count;
-       spin_unlock(&drm_mem_lock);
-       if (free_count > alloc_count) {
-               DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
-                             free_count, alloc_count);
-       }
-}
-
-unsigned long drm_alloc_pages(int order, int area)
-{
-       unsigned long address;
-       unsigned long bytes       = PAGE_SIZE << order;
-       unsigned long addr;
-       unsigned int  sz;
-       
-       spin_lock(&drm_mem_lock);
-       if ((drm_ram_used >> PAGE_SHIFT)
-           > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
-               spin_unlock(&drm_mem_lock);
-               return 0;
-       }
-       spin_unlock(&drm_mem_lock);
-       
-       address = __get_free_pages(GFP_KERNEL, order);
-       if (!address) {
-               spin_lock(&drm_mem_lock);
-               ++drm_mem_stats[area].fail_count;
-               spin_unlock(&drm_mem_lock);
-               return 0;
-       }
-       spin_lock(&drm_mem_lock);
-       ++drm_mem_stats[area].succeed_count;
-       drm_mem_stats[area].bytes_allocated += bytes;
-       drm_ram_used                        += bytes;
-       spin_unlock(&drm_mem_lock);
-       
-       
-                               /* Zero outside the lock */
-       memset((void *)address, 0, bytes);
-       
-                               /* Reserve */
-       for (addr = address, sz = bytes;
-            sz > 0;
-            addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* Argument type changed in 2.4.0-test6/pre8 */
-               mem_map_reserve(virt_to_page(addr));
-#else
-               mem_map_reserve(MAP_NR(addr));
-#endif
-       }
-       
-       return address;
-}
-
-void drm_free_pages(unsigned long address, int order, int area)
-{
-       unsigned long bytes = PAGE_SIZE << order;
-       int               alloc_count;
-       int               free_count;
-       unsigned long addr;
-       unsigned int  sz;
-       
-       if (!address) {
-               DRM_MEM_ERROR(area, "Attempt to free address 0\n");
-       } else {
-                               /* Unreserve */
-               for (addr = address, sz = bytes;
-                    sz > 0;
-                    addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* Argument type changed in 2.4.0-test6/pre8 */
-                       mem_map_unreserve(virt_to_page(addr));
-#else
-                       mem_map_unreserve(MAP_NR(addr));
-#endif
-               }
-               free_pages(address, order);
-       }
-       
-       spin_lock(&drm_mem_lock);
-       free_count  = ++drm_mem_stats[area].free_count;
-       alloc_count =   drm_mem_stats[area].succeed_count;
-       drm_mem_stats[area].bytes_freed += bytes;
-       drm_ram_used                    -= bytes;
-       spin_unlock(&drm_mem_lock);
-       if (free_count > alloc_count) {
-               DRM_MEM_ERROR(area,
-                             "Excess frees: %d frees, %d allocs\n",
-                             free_count, alloc_count);
-       }
-}
-
-void *drm_ioremap(unsigned long offset, unsigned long size)
-{
-       void *pt;
-       
-       if (!size) {
-               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
-                             "Mapping 0 bytes at 0x%08lx\n", offset);
-               return NULL;
-       }
-       
-       if (!(pt = ioremap(offset, size))) {
-               spin_lock(&drm_mem_lock);
-               ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
-               spin_unlock(&drm_mem_lock);
-               return NULL;
-       }
-       spin_lock(&drm_mem_lock);
-       ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
-       drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
-       spin_unlock(&drm_mem_lock);
-       return pt;
-}
-
-void drm_ioremapfree(void *pt, unsigned long size)
-{
-       int alloc_count;
-       int free_count;
-       
-       if (!pt)
-               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
-                             "Attempt to free NULL pointer\n");
-       else
-               iounmap(pt);
-       
-       spin_lock(&drm_mem_lock);
-       drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
-       free_count  = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
-       alloc_count =   drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
-       spin_unlock(&drm_mem_lock);
-       if (free_count > alloc_count) {
-               DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
-                             "Excess frees: %d frees, %d allocs\n",
-                             free_count, alloc_count);
-       }
-}
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-agp_memory *drm_alloc_agp(int pages, u32 type)
-{
-       agp_memory *handle;
-
-       if (!pages) {
-               DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
-               return NULL;
-       }
-       
-       if ((handle = drm_agp_allocate_memory(pages, type))) {
-               spin_lock(&drm_mem_lock);
-               ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
-               drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
-                       += pages << PAGE_SHIFT;
-               spin_unlock(&drm_mem_lock);
-               return handle;
-       }
-       spin_lock(&drm_mem_lock);
-       ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
-       spin_unlock(&drm_mem_lock);
-       return NULL;
-}
-
-int drm_free_agp(agp_memory *handle, int pages)
-{
-       int           alloc_count;
-       int           free_count;
-       int           retval = -EINVAL;
-
-       if (!handle) {
-               DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
-                             "Attempt to free NULL AGP handle\n");
-               return retval;;
-       }
-       
-       if (drm_agp_free_memory(handle)) {
-               spin_lock(&drm_mem_lock);
-               free_count  = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
-               alloc_count =   drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
-               drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
-                       += pages << PAGE_SHIFT;
-               spin_unlock(&drm_mem_lock);
-               if (free_count > alloc_count) {
-                       DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
-                                     "Excess frees: %d frees, %d allocs\n",
-                                     free_count, alloc_count);
-               }
-               return 0;
-       }
-       return retval;
-}
-
-int drm_bind_agp(agp_memory *handle, unsigned int start)
-{
-       int retcode = -EINVAL;
-
-       if (!handle) {
-               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
-                             "Attempt to bind NULL AGP handle\n");
-               return retcode;
-       }
-
-       if (!(retcode = drm_agp_bind_memory(handle, start))) {
-               spin_lock(&drm_mem_lock);
-               ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
-               drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
-                       += handle->page_count << PAGE_SHIFT;
-               spin_unlock(&drm_mem_lock);
-               return retcode;
-       }
-       spin_lock(&drm_mem_lock);
-       ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
-       spin_unlock(&drm_mem_lock);
-       return retcode;
-}
-
-int drm_unbind_agp(agp_memory *handle)
-{
-       int alloc_count;
-       int free_count;
-       int retcode = -EINVAL;
-       
-       if (!handle) {
-               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
-                             "Attempt to unbind NULL AGP handle\n");
-               return retcode;
-       }
-
-       if ((retcode = drm_agp_unbind_memory(handle))) return retcode;
-       spin_lock(&drm_mem_lock);
-       free_count  = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
-       alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
-       drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
-               += handle->page_count << PAGE_SHIFT;
-       spin_unlock(&drm_mem_lock);
-       if (free_count > alloc_count) {
-               DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
-                             "Excess frees: %d frees, %d allocs\n",
-                             free_count, alloc_count);
-       }
-       return retcode;
-}
-#endif
diff --git a/drivers/char/drm/mga.h b/drivers/char/drm/mga.h
new file mode 100644 (file)
index 0000000..277aa20
--- /dev/null
@@ -0,0 +1,67 @@
+/* mga.h -- Matrox G200/G400 DRM template customization -*- linux-c -*-
+ * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __MGA_H__
+#define __MGA_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) mga_##x
+
+/* General customization:
+ */
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+
+/* Driver customization:
+ */
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) mga_do_cleanup_dma( dev );              \
+} while (0)
+
+/* DMA customization:
+ */
+#define __HAVE_DMA             1
+
+#define __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       drm_mga_private_t *dev_priv = dev->dev_private;                 \
+       return mga_do_wait_for_idle( dev_priv );                        \
+} while (0)
+
+/* Buffer customization:
+ */
+#define DRIVER_BUF_PRIV_T      drm_mga_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_mga_private_t *)((dev)->dev_private))->buffers
+
+#endif
diff --git a/drivers/char/drm/mga_bufs.c b/drivers/char/drm/mga_bufs.c
deleted file mode 100644 (file)
index e99293a..0000000
+++ /dev/null
@@ -1,629 +0,0 @@
-/* mga_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
- * Created: Thu Jan 6 01:47:26 2000 by jhartmann@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "mga_drv.h"
-#include "linux/un.h"
-
-
-int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
-{
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->dev;
-       drm_device_dma_t *dma = dev->dma;
-       drm_buf_desc_t request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       count = request.count;
-       order = drm_order(request.size);
-       size    = 1 << order;
-       agp_offset = request.agp_start;
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
-       page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-       total = PAGE_SIZE << page_order;
-       byte_count = 0;
-
-       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);
-       DRM_DEBUG("byte_count: %d\n", byte_count);
-
-       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-   
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-
-       /* This isnt neccessarily a good limit, but we have to stop a dumb
-          32 bit overflow problem below */
-          
-       if ( count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -EINVAL;
-       }
-                  
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -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 = offset; /* Hrm */
-               buf->bus_address = dev->agp->base + agp_offset + offset;
-               buf->address = (void *)(agp_offset + offset + dev->agp->base);
-               buf->next = NULL;
-               buf->waiting = 0;
-               buf->pending = 0;
-               init_waitqueue_head(&buf->dma_wait);
-               buf->pid = 0;
-
-               buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t),
-                                            DRM_MEM_BUFS);
-               buf->dev_priv_size = sizeof(drm_mga_buf_priv_t);
-
-#if DRM_DMA_HISTOGRAM
-               buf->time_queued = 0;
-               buf->time_dispatched = 0;
-               buf->time_completed = 0;
-               buf->time_freed = 0;
-#endif
-               offset = offset + alignment;
-               entry->buf_count++;
-               byte_count += PAGE_SIZE << page_order;
-       }
-   
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-   
-       dma->buf_count  += entry->buf_count;
-
-       DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
-
-       dma->byte_count += byte_count;
-
-       DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
-
-       drm_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-   
-       up(&dev->struct_sem);
-   
-       request.count = entry->buf_count;
-       request.size  = size;
-   
-       if (copy_to_user((drm_buf_desc_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-   
-       atomic_dec(&dev->buf_alloc);
-
-       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);
-       DRM_DEBUG("byte_count: %d\n", byte_count);
-
-       dma->flags = _DRM_DMA_USE_AGP;
-
-       DRM_DEBUG("dma->flags : %x\n", dma->flags);
-
-       return 0;
-}
-
-int mga_addbufs_pci(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_desc_t   request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       count      = request.count;
-       order      = drm_order(request.size);
-       size       = 1 << order;
-       
-       DRM_DEBUG("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
-                 request.count, request.size, size, order, dev->queue_count);
-
-       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
-       page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
-       total      = PAGE_SIZE << page_order;
-
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-       
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-       
-       if(count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -EINVAL;
-       }
-       
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -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);
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM;
-       }
-       memset(entry->seglist, 0, count * sizeof(*entry->seglist));
-
-       dma->pagelist = drm_realloc(dma->pagelist,
-                                   dma->page_count * sizeof(*dma->pagelist),
-                                   (dma->page_count + (count << page_order))
-                                   * sizeof(*dma->pagelist),
-                                   DRM_MEM_PAGES);
-       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) {
-               if (!(page = drm_alloc_pages(page_order, DRM_MEM_DMA))) 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->waiting = 0;
-                       buf->pending = 0;
-                       init_waitqueue_head(&buf->dma_wait);
-                       buf->pid     = 0;
-#if DRM_DMA_HISTOGRAM
-                       buf->time_queued     = 0;
-                       buf->time_dispatched = 0;
-                       buf->time_completed  = 0;
-                       buf->time_freed      = 0;
-#endif
-                       DRM_DEBUG("buffer %d @ %p\n",
-                                 entry->buf_count, buf->address);
-               }
-               byte_count += PAGE_SIZE << page_order;
-       }
-
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
-       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_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-       
-       up(&dev->struct_sem);
-
-       request.count = entry->buf_count;
-       request.size  = size;
-
-       if (copy_to_user((drm_buf_desc_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-       
-       atomic_dec(&dev->buf_alloc);
-       return 0;
-}
-
-int mga_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_buf_desc_t   request;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       if(request.flags & _DRM_AGP_BUFFER)
-               return mga_addbufs_agp(inode, filp, cmd, arg);
-       else
-               return mga_addbufs_pci(inode, filp, cmd, arg);
-}
-
-int mga_infobufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_info_t   request;
-       int              i;
-       int              count;
-
-       if (!dma) return -EINVAL;
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_info_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
-               if (dma->bufs[i].buf_count) ++count;
-       }
-       
-       if (request.count >= count) {
-               for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
-                       if (dma->bufs[i].buf_count) {
-                               if (copy_to_user(&request.list[count].count,
-                                                &dma->bufs[i].buf_count,
-                                                sizeof(dma->bufs[0]
-                                                       .buf_count)) ||
-                                   copy_to_user(&request.list[count].size,
-                                                &dma->bufs[i].buf_size,
-                                                sizeof(dma->bufs[0].buf_size)) ||
-                                   copy_to_user(&request.list[count].low_mark,
-                                                &dma->bufs[i]
-                                                .freelist.low_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.low_mark)) ||
-                                   copy_to_user(&request.list[count]
-                                                .high_mark,
-                                                &dma->bufs[i]
-                                                .freelist.high_mark,
-                                                sizeof(dma->bufs[0]
-                                                       .freelist.high_mark)))
-                                       return -EFAULT;
-                               ++count;
-                       }
-               }
-       }
-       request.count = count;
-
-       if (copy_to_user((drm_buf_info_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-       
-       return 0;
-}
-
-int mga_markbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_desc_t   request;
-       int              order;
-       drm_buf_entry_t  *entry;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
-               return -EFAULT;
-
-       order = drm_order(request.size);
-       if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
-       entry = &dma->bufs[order];
-
-       if (request.low_mark < 0 || request.low_mark > entry->buf_count)
-               return -EINVAL;
-       if (request.high_mark < 0 || request.high_mark > entry->buf_count)
-               return -EINVAL;
-
-       entry->freelist.low_mark  = request.low_mark;
-       entry->freelist.high_mark = request.high_mark;
-       
-       return 0;
-}
-
-int mga_freebufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       drm_buf_free_t   request;
-       int              i;
-       int              idx;
-       drm_buf_t        *buf;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_free_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       for (i = 0; i < request.count; i++) {
-               if (copy_from_user(&idx,
-                                  &request.list[i],
-                                  sizeof(idx)))
-                       return -EFAULT;
-               if (idx < 0 || idx >= dma->buf_count) {
-                       DRM_ERROR("Index %d (of %d max)\n",
-                                 idx, dma->buf_count - 1);
-                       return -EINVAL;
-               }
-               buf = dma->buflist[idx];
-               if (buf->pid != current->pid) {
-                       DRM_ERROR("Process %d freeing buffer owned by %d\n",
-                                 current->pid, buf->pid);
-                       return -EINVAL;
-               }
-               drm_free_buffer(dev, buf);
-       }
-       
-       return 0;
-}
-
-int mga_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       int              retcode = 0;
-       const int        zero    = 0;
-       unsigned long    virtual;
-       unsigned long    address;
-       drm_buf_map_t    request;
-       int              i;
-
-       if (!dma) return -EINVAL;
-       
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_map_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       if (request.count >= dma->buf_count) {
-               if(dma->flags & _DRM_DMA_USE_AGP) {
-                       drm_mga_private_t *dev_priv = dev->dev_private;
-                       drm_map_t *map = NULL;
-        
-                       map = dev->maplist[dev_priv->buffer_map_idx];
-                       if (!map) {
-                               retcode = -EINVAL;
-                               goto done;
-                       }
-
-                       DRM_DEBUG("map->offset : %lx\n", map->offset);
-                       DRM_DEBUG("map->size : %lx\n", map->size);
-                       DRM_DEBUG("map->type : %d\n", map->type);
-                       DRM_DEBUG("map->flags : %x\n", map->flags);
-                       DRM_DEBUG("map->handle : %p\n", map->handle);
-                       DRM_DEBUG("map->mtrr : %d\n", map->mtrr);
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size, 
-                                         PROT_READ|PROT_WRITE,
-                                         MAP_SHARED, 
-                                         (unsigned long)map->offset);
-                       up_write(&current->mm->mmap_sem);
-               } else {
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
-                                         PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-                       up_write(&current->mm->mmap_sem);
-               }
-               if (virtual > -1024UL) {
-                       /* Real error */
-                       DRM_DEBUG("mmap error\n");
-                       retcode = (signed long)virtual;
-                       goto done;
-               }
-               request.virtual = (void *)virtual;
-      
-               for (i = 0; i < dma->buf_count; i++) {
-                       if (copy_to_user(&request.list[i].idx,
-                                        &dma->buflist[i]->idx,
-                                        sizeof(request.list[0].idx))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].total,
-                                        &dma->buflist[i]->total,
-                                        sizeof(request.list[0].total))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].used,
-                                        &zero,
-                                        sizeof(zero))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       address = virtual + dma->buflist[i]->offset;
-                       if (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);
-   
-       if (copy_to_user((drm_buf_map_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-
-       DRM_DEBUG("retcode : %d\n", retcode);
-
-       return retcode;
-}
diff --git a/drivers/char/drm/mga_context.c b/drivers/char/drm/mga_context.c
deleted file mode 100644 (file)
index b26c7c9..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/* mga_context.c -- IOCTLs for mga contexts -*- linux-c -*-
- * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Author: Rickard E. (Rik) Faith <faith@valinux.com>
- *        Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "mga_drv.h"
-
-static int mga_alloc_queue(drm_device_t *dev)
-{
-       return drm_ctxbitmap_next(dev);
-}
-
-int mga_context_switch(drm_device_t *dev, int old, int new)
-{
-        char        buf[64];
-
-        atomic_inc(&dev->total_ctx);
-
-        if (test_and_set_bit(0, &dev->context_flag)) {
-                DRM_ERROR("Reentering -- FIXME\n");
-                return -EBUSY;
-        }
-
-#if DRM_DMA_HISTOGRAM
-        dev->ctx_start = get_cycles();
-#endif
-        
-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-        if (new == dev->last_context) {
-                clear_bit(0, &dev->context_flag);
-                return 0;
-        }
-        
-        if (drm_flags & DRM_FLAG_NOCTX) {
-                mga_context_switch_complete(dev, new);
-        } else {
-                sprintf(buf, "C %d %d\n", old, new);
-                drm_write_string(dev, buf);
-        }
-        
-        return 0;
-}
-
-int mga_context_switch_complete(drm_device_t *dev, int new)
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-        
-        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. */
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                      - dev->ctx_start)]);
-                   
-#endif
-        clear_bit(0, &dev->context_flag);
-        wake_up(&dev->context_wait);
-        
-        return 0;
-}
-
-int mga_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i],
-                                        &i,
-                                        sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-int mga_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = mga_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Skip kernel's context and get a new one. */
-               ctx.handle = mga_alloc_queue(dev);
-       }
-        if (ctx.handle == -1) {
-               return -ENOMEM;
-       }
-       DRM_DEBUG("%d\n", ctx.handle);
-       if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int mga_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       /* This does nothing for the mga */
-       return 0;
-}
-
-int mga_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       /* This is 0, because we don't hanlde any context flags */
-       ctx.flags = 0;
-       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int mga_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return mga_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int mga_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       mga_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int mga_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       if(ctx.handle == DRM_KERNEL_CONTEXT+1) priv->remove_auth_on_close = 1;
-
-       if(ctx.handle != DRM_KERNEL_CONTEXT) {
-               drm_ctxbitmap_free(dev, ctx.handle);
-       }
-       
-       return 0;
-}
index 356376ca9cfeaae2cc6dea827c659572b045061e..2a151361c70042183b279f556a703de77edba91a 100644 (file)
  * 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>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *         Keith Whitwell <keithw@valinux.com>
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Jeff Hartmann <jhartmann@valinux.com>
+ *    Keith Whitwell <keithw@valinux.com>
  *
+ * Rewritten by:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "mga.h"
 #include "drmP.h"
 #include "mga_drv.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
+#include <linux/delay.h>
 
-#define MGA_REG(reg)           2
-#define MGA_BASE(reg)          ((unsigned long) \
-                               ((drm_device_t *)dev)->maplist[MGA_REG(reg)]->handle)
-#define MGA_ADDR(reg)          (MGA_BASE(reg) + reg)
-#define MGA_DEREF(reg)         *(__volatile__ int *)MGA_ADDR(reg)
-#define MGA_READ(reg)          MGA_DEREF(reg)
-#define MGA_WRITE(reg,val)     do { MGA_DEREF(reg) = val; } while (0)
+#define MGA_DEFAULT_USEC_TIMEOUT       10000
+#define MGA_FREELIST_DEBUG             0
 
-#define PDEA_pagpxfer_enable        0x2
 
-static int mga_flush_queue(drm_device_t *dev);
+/* ================================================================
+ * Engine control
+ */
 
-static unsigned long mga_alloc_page(drm_device_t *dev)
+int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
 {
-       unsigned long address;
+       u32 status = 0;
+       int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       address = __get_free_page(GFP_KERNEL);
-       if(address == 0UL) {
-               return 0;
+       for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+               status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+               if ( status == MGA_ENDPRDMASTS ) {
+                       MGA_WRITE8( MGA_CRTC_INDEX, 0 );
+                       return 0;
+               }
+               udelay( 1 );
        }
-       atomic_inc(&virt_to_page(address)->count);
-       set_bit(PG_reserved, &virt_to_page(address)->flags);
 
-       return address;
+#if MGA_DMA_DEBUG
+       DRM_ERROR( "failed!\n" );
+       DRM_INFO( "   status=0x%08x\n", status );
+#endif
+       return -EBUSY;
 }
 
-static void mga_free_page(drm_device_t *dev, unsigned long page)
+int mga_do_dma_idle( drm_mga_private_t *dev_priv )
 {
-       if(!page) return;
-       atomic_dec(&virt_to_page(page)->count);
-       clear_bit(PG_reserved, &virt_to_page(page)->flags);
-       free_page(page);
-       return;
+       u32 status = 0;
+       int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+               status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK;
+               if ( status == MGA_ENDPRDMASTS ) return 0;
+               udelay( 1 );
+       }
+
+#if MGA_DMA_DEBUG
+       DRM_ERROR( "failed! status=0x%08x\n", status );
+#endif
+       return -EBUSY;
 }
 
-static void mga_delay(void)
+int mga_do_dma_reset( drm_mga_private_t *dev_priv )
 {
-       return;
-}
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 
-/* These are two age tags that will never be sent to
- * the hardware */
-#define MGA_BUF_USED   0xffffffff
-#define MGA_BUF_FREE   0
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-static int mga_freelist_init(drm_device_t *dev)
-{
-       drm_device_dma_t *dma = dev->dma;
-       drm_buf_t *buf;
-       drm_mga_buf_priv_t *buf_priv;
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       drm_mga_freelist_t *item;
-       int i;
-
-       dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
-       if(dev_priv->head == NULL) return -ENOMEM;
-       memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
-       dev_priv->head->age = MGA_BUF_USED;
-
-       for (i = 0; i < dma->buf_count; i++) {
-               buf = dma->buflist[ i ];
-               buf_priv = buf->dev_private;
-               item = drm_alloc(sizeof(drm_mga_freelist_t),
-                                DRM_MEM_DRIVER);
-               if(item == NULL) return -ENOMEM;
-               memset(item, 0, sizeof(drm_mga_freelist_t));
-               item->age = MGA_BUF_FREE;
-               item->prev = dev_priv->head;
-               item->next = dev_priv->head->next;
-               if(dev_priv->head->next != NULL)
-                       dev_priv->head->next->prev = item;
-               if(item->next == NULL) dev_priv->tail = item;
-               item->buf = buf;
-               buf_priv->my_freelist = item;
-               buf_priv->discard = 0;
-               buf_priv->dispatched = 0;
-               dev_priv->head->next = item;
-       }
+       /* The primary DMA stream should look like new right about now.
+        */
+       primary->tail = 0;
+       primary->space = primary->size;
+       primary->last_flush = 0;
 
-       return 0;
-}
+       sarea_priv->last_wrap = 0;
 
-static void mga_freelist_cleanup(drm_device_t *dev)
-{
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       drm_mga_freelist_t *item;
-       drm_mga_freelist_t *prev;
-
-       item = dev_priv->head;
-       while(item) {
-               prev = item;
-               item = item->next;
-               drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
-       }
+       /* FIXME: Reset counters, buffer ages etc...
+        */
+
+       /* FIXME: What else do we need to reinitialize?  WARP stuff?
+        */
 
-       dev_priv->head = dev_priv->tail = NULL;
+       return 0;
 }
 
-/* Frees dispatch lock */
-static inline void mga_dma_quiescent(drm_device_t *dev)
+int mga_do_engine_reset( drm_mga_private_t *dev_priv )
 {
-       drm_device_dma_t  *dma      = dev->dma;
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned long end;
-       int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       DRM_DEBUG("dispatch_status = 0x%02lx\n", dev_priv->dispatch_status);
-       end = jiffies + (HZ*3);
-       while(1) {
-               if(!test_and_set_bit(MGA_IN_DISPATCH,
-                                    &dev_priv->dispatch_status)) {
-                       break;
-               }
-               if((signed)(end - jiffies) <= 0) {
-                       DRM_ERROR("irqs: %d wanted %d\n",
-                                 atomic_read(&dev->total_irq),
-                                 atomic_read(&dma->total_lost));
-                       DRM_ERROR("lockup: dispatch_status = 0x%02lx,"
-                                 " jiffies = %lu, end = %lu\n",
-                                 dev_priv->dispatch_status, jiffies, end);
-                       return;
-               }
-               for (i = 0 ; i < 2000 ; i++) mga_delay();
-       }
-       end = jiffies + (HZ*3);
-       DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
-       while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
-               if((signed)(end - jiffies) <= 0) {
-                       DRM_ERROR("irqs: %d wanted %d\n",
-                                 atomic_read(&dev->total_irq),
-                                 atomic_read(&dma->total_lost));
-                       DRM_ERROR("lockup\n");
-                       clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-                       return;
-               }
-               for (i = 0 ; i < 2000 ; i++) mga_delay();
-       }
-       sarea_priv->dirty |= MGA_DMA_FLUSH;
+       /* Okay, so we've completely screwed up and locked the engine.
+        * How about we clean up after ourselves?
+        */
+       MGA_WRITE( MGA_RST, MGA_SOFTRESET );
+       udelay( 15 );                           /* Wait at least 10 usecs */
+       MGA_WRITE( MGA_RST, 0 );
+
+       /* Initialize the registers that get clobbered by the soft
+        * reset.  Many of the core register values survive a reset,
+        * but the drawing registers are basically all gone.
+        *
+        * 3D clients should probably die after calling this.  The X
+        * server should reset the engine state to known values.
+        */
+#if 0
+       MGA_WRITE( MGA_PRIMPTR,
+                  virt_to_bus((void *)dev_priv->prim.status_page) |
+                  MGA_PRIMPTREN0 |
+                  MGA_PRIMPTREN1 );
+#endif
 
-       clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-       DRM_DEBUG("exit, dispatch_status = 0x%02lx\n",
-                 dev_priv->dispatch_status);
-}
+       MGA_WRITE( MGA_ICLEAR, MGA_SOFTRAPICLR );
+       MGA_WRITE( MGA_IEN,    MGA_SOFTRAPIEN );
 
-static void mga_reset_freelist(drm_device_t *dev)
-{
-       drm_device_dma_t  *dma      = dev->dma;
-       drm_buf_t *buf;
-       drm_mga_buf_priv_t *buf_priv;
-       int i;
+       /* The primary DMA stream should look like new right about now.
+        */
+       mga_do_dma_reset( dev_priv );
 
-       for (i = 0; i < dma->buf_count; i++) {
-               buf = dma->buflist[ i ];
-               buf_priv = buf->dev_private;
-               buf_priv->my_freelist->age = MGA_BUF_FREE;
-       }
+       /* This bad boy will never fail.
+        */
+       return 0;
 }
 
-/* Least recently used :
- * These operations are not atomic b/c they are protected by the
- * hardware lock */
 
-drm_buf_t *mga_freelist_get(drm_device_t *dev)
+/* ================================================================
+ * Primary DMA stream
+ */
+
+void mga_do_dma_flush( drm_mga_private_t *dev_priv )
 {
-       DECLARE_WAITQUEUE(entry, current);
-       drm_mga_private_t *dev_priv =
-               (drm_mga_private_t *) dev->dev_private;
-       drm_mga_freelist_t *prev;
-       drm_mga_freelist_t *next;
-       static int failed = 0;
-       int return_null = 0;
-
-       if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
-               DRM_DEBUG("Waiting on freelist,"
-                         " tail->age = %d, last_prim_age= %d\n",
-                         dev_priv->tail->age,
-                         dev_priv->last_prim_age);
-               add_wait_queue(&dev_priv->buf_queue, &entry);
-               set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       mga_dma_schedule(dev, 0);
-                       if(dev_priv->tail->age < dev_priv->last_prim_age)
-                               break;
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               ++return_null;
-                               break;
-                       }
-               }
-               clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev_priv->buf_queue, &entry);
-               if (return_null) return NULL;
-       }
+       drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+       u32 head, tail;
+       DMA_LOCALS;
+       DRM_DEBUG( "%s:\n", __FUNCTION__ );
 
-       if(dev_priv->tail->age < dev_priv->last_prim_age) {
-               prev = dev_priv->tail->prev;
-               next = dev_priv->tail;
-               prev->next = NULL;
-               next->prev = next->next = NULL;
-               dev_priv->tail = prev;
-               next->age = MGA_BUF_USED;
-               failed = 0;
-               return next->buf;
+       if ( primary->tail == primary->last_flush ) {
+               DRM_DEBUG( "   bailing out...\n" );
+               return;
        }
 
-       failed++;
-       return NULL;
-}
+       tail = primary->tail + dev_priv->primary->offset;
 
-int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
-{
-       drm_mga_private_t *dev_priv =
-               (drm_mga_private_t *) dev->dev_private;
-       drm_mga_buf_priv_t *buf_priv = buf->dev_private;
-       drm_mga_freelist_t *prev;
-       drm_mga_freelist_t *head;
-       drm_mga_freelist_t *next;
+       /* We need to pad the stream between flushes, as the card
+        * actually (partially?) reads the first of these commands.
+        * See page 4-16 in the G400 manual, middle of the page or so.
+        */
+       BEGIN_DMA( 1 );
 
-       if(buf_priv->my_freelist->age == MGA_BUF_USED) {
-               /* Discarded buffer, put it on the tail */
-               next = buf_priv->my_freelist;
-               next->age = MGA_BUF_FREE;
-               prev = dev_priv->tail;
-               prev->next = next;
-               next->prev = prev;
-               next->next = NULL;
-               dev_priv->tail = next;
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000 );
+
+       ADVANCE_DMA();
+
+       primary->last_flush = primary->tail;
+
+       head = MGA_READ( MGA_PRIMADDRESS );
+
+       if ( head <= tail ) {
+               primary->space = primary->size - primary->tail;
        } else {
-               /* Normally aged buffer, put it on the head + 1,
-                * as the real head is a sentinal element
-                */
-               next = buf_priv->my_freelist;
-               head = dev_priv->head;
-               prev = head->next;
-               head->next = next;
-               prev->prev = next;
-               next->prev = head;
-               next->next = prev;
+               primary->space = head - tail;
        }
 
-       return 0;
+       DRM_DEBUG( "   head = 0x%06lx\n", head - dev_priv->primary->offset );
+       DRM_DEBUG( "   tail = 0x%06lx\n", tail - dev_priv->primary->offset );
+       DRM_DEBUG( "  space = 0x%06x\n", primary->space );
+
+       mga_flush_write_combine();
+       MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
+
+       DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
 }
 
-static int mga_init_primary_bufs(drm_device_t *dev, drm_mga_init_t *init)
+void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
 {
-       drm_mga_private_t *dev_priv = dev->dev_private;
-       drm_mga_prim_buf_t *prim_buffer;
-       int i, temp, size_of_buf;
-       int offset = init->reserved_map_agpstart;
-
-       dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
-                                 PAGE_SIZE) * PAGE_SIZE;
-       size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
-       dev_priv->warp_ucode_size = init->warp_ucode_size;
-       dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
-                                       (MGA_NUM_PRIM_BUFS + 1),
-                                       DRM_MEM_DRIVER);
-       if(dev_priv->prim_bufs == NULL) {
-               DRM_ERROR("Unable to allocate memory for prim_buf\n");
-               return -ENOMEM;
-       }
-       memset(dev_priv->prim_bufs,
-              0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
+       drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+       u32 head, tail;
+       DMA_LOCALS;
+       DRM_DEBUG( "%s:\n", __FUNCTION__ );
 
-       temp = init->warp_ucode_size + dev_priv->primary_size;
-       temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
+       BEGIN_DMA_WRAP();
 
-       dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
-                                       temp);
-       if(dev_priv->ioremap == NULL) {
-               DRM_ERROR("Ioremap failed\n");
-               return -ENOMEM;
-       }
-       init_waitqueue_head(&dev_priv->wait_queue);
-
-       for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
-               prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
-                                       DRM_MEM_DRIVER);
-               if(prim_buffer == NULL) return -ENOMEM;
-               memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
-               prim_buffer->phys_head = offset + dev->agp->base;
-               prim_buffer->current_dma_ptr =
-                       prim_buffer->head =
-                       (u32 *) (dev_priv->ioremap +
-                                offset -
-                                init->reserved_map_agpstart);
-               prim_buffer->num_dwords = 0;
-               prim_buffer->max_dwords = size_of_buf / sizeof(u32);
-               prim_buffer->max_dwords -= 5; /* Leave room for the softrap */
-               prim_buffer->sec_used = 0;
-               prim_buffer->idx = i;
-               prim_buffer->prim_age = i + 1;
-               offset = offset + size_of_buf;
-               dev_priv->prim_bufs[i] = prim_buffer;
-       }
-       dev_priv->current_prim_idx = 0;
-        dev_priv->next_prim =
-               dev_priv->last_prim =
-               dev_priv->current_prim =
-               dev_priv->prim_bufs[0];
-       dev_priv->next_prim_age = 2;
-       dev_priv->last_prim_age = 1;
-       set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
-       return 0;
-}
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000 );
 
-void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
-{
-               drm_mga_private_t *dev_priv = dev->dev_private;
-       drm_device_dma_t  *dma      = dev->dma;
-               drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       int use_agp = PDEA_pagpxfer_enable;
-       unsigned long end;
-       int i;
-       int next_idx;
-               PRIMLOCALS;
-
-       dev_priv->last_prim = prim;
-
-       /* We never check for overflow, b/c there is always room */
-       PRIMPTR(prim);
-       if(num_dwords <= 0) {
-               DRM_ERROR("num_dwords == 0 when dispatched\n");
-               goto out_prim_wait;
-       }
-       PRIMOUTREG( MGAREG_DMAPAD, 0);
-       PRIMOUTREG( MGAREG_DMAPAD, 0);
-               PRIMOUTREG( MGAREG_DMAPAD, 0);
-       PRIMOUTREG( MGAREG_SOFTRAP, 0);
-       PRIMFINISH(prim);
-
-       end = jiffies + (HZ*3);
-       if(sarea_priv->dirty & MGA_DMA_FLUSH) {
-               while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
-                       if((signed)(end - jiffies) <= 0) {
-                               DRM_ERROR("irqs: %d wanted %d\n",
-                                         atomic_read(&dev->total_irq),
-                                         atomic_read(&dma->total_lost));
-                               DRM_ERROR("lockup (flush)\n");
-                               goto out_prim_wait;
-                       }
-
-                       for (i = 0 ; i < 4096 ; i++) mga_delay();
-               }
-               sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
+       ADVANCE_DMA();
+
+       tail = primary->tail + dev_priv->primary->offset;
+
+       primary->tail = 0;
+       primary->last_flush = 0;
+       primary->last_wrap++;
+
+       head = MGA_READ( MGA_PRIMADDRESS );
+
+       if ( head == dev_priv->primary->offset ) {
+               primary->space = primary->size;
        } else {
-               while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
-                       if((signed)(end - jiffies) <= 0) {
-                               DRM_ERROR("irqs: %d wanted %d\n",
-                                         atomic_read(&dev->total_irq),
-                                         atomic_read(&dma->total_lost));
-                               DRM_ERROR("lockup (wait)\n");
-                               goto out_prim_wait;
-                       }
-
-                       for (i = 0 ; i < 4096 ; i++) mga_delay();
-               }
+               primary->space = head - dev_priv->primary->offset;
        }
 
-       mga_flush_write_combine();
-       atomic_inc(&dev_priv->pending_bufs);
-               MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
-       MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
-       prim->num_dwords = 0;
-       sarea_priv->last_enqueue = prim->prim_age;
-
-       next_idx = prim->idx + 1;
-       if(next_idx >= MGA_NUM_PRIM_BUFS)
-               next_idx = 0;
-
-       dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
-       return;
-
- out_prim_wait:
-       prim->num_dwords = 0;
-       prim->sec_used = 0;
-       clear_bit(MGA_BUF_IN_USE, &prim->buffer_status);
-       wake_up_interruptible(&dev_priv->wait_queue);
-       clear_bit(MGA_BUF_SWAP_PENDING, &prim->buffer_status);
-       clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
+       DRM_DEBUG( "   head = 0x%06lx\n",
+                 head - dev_priv->primary->offset );
+       DRM_DEBUG( "   tail = 0x%06x\n", primary->tail );
+       DRM_DEBUG( "   wrap = %d\n", primary->last_wrap );
+       DRM_DEBUG( "  space = 0x%06x\n", primary->space );
+
+       mga_flush_write_combine();
+       MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
+
+       set_bit( 0, &primary->wrapped );
+       DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
 }
 
-int mga_advance_primary(drm_device_t *dev)
+void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
 {
-       DECLARE_WAITQUEUE(entry, current);
-       drm_mga_private_t *dev_priv = dev->dev_private;
-       drm_mga_prim_buf_t *prim_buffer;
-       drm_device_dma_t  *dma      = dev->dma;
-       int next_prim_idx;
-       int ret = 0;
-
-       /* This needs to reset the primary buffer if available,
-        * we should collect stats on how many times it bites
-        * it's tail */
-
-       next_prim_idx = dev_priv->current_prim_idx + 1;
-       if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
-               next_prim_idx = 0;
-       prim_buffer = dev_priv->prim_bufs[next_prim_idx];
-       set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-
-       /* In use is cleared in interrupt handler */
-
-       if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
-               add_wait_queue(&dev_priv->wait_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       mga_dma_schedule(dev, 0);
-                       if(!test_and_set_bit(MGA_BUF_IN_USE,
-                                            &prim_buffer->buffer_status))
-                               break;
-                       atomic_inc(&dev->total_sleeps);
-                       atomic_inc(&dma->total_missed_sched);
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev_priv->wait_queue, &entry);
-               if(ret) return ret;
-       }
-       clear_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-
-       /* This primary buffer is now free to use */
-       prim_buffer->current_dma_ptr = prim_buffer->head;
-       prim_buffer->num_dwords = 0;
-       prim_buffer->sec_used = 0;
-       prim_buffer->prim_age = dev_priv->next_prim_age++;
-       if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
-               mga_flush_queue(dev);
-               mga_dma_quiescent(dev);
-               mga_reset_freelist(dev);
-               prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
-       }
+       drm_mga_primary_buffer_t *primary = &dev_priv->prim;
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       u32 head = dev_priv->primary->offset;
+       DRM_DEBUG( "%s:\n", __FUNCTION__ );
+
+       sarea_priv->last_wrap++;
+       DRM_DEBUG( "   wrap = %d\n", sarea_priv->last_wrap );
 
-       /* Reset all buffer status stuff */
-       clear_bit(MGA_BUF_NEEDS_OVERFLOW, &prim_buffer->buffer_status);
-       clear_bit(MGA_BUF_FORCE_FIRE, &prim_buffer->buffer_status);
-       clear_bit(MGA_BUF_SWAP_PENDING, &prim_buffer->buffer_status);
+       mga_flush_write_combine();
+       MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
 
-       dev_priv->current_prim = prim_buffer;
-       dev_priv->current_prim_idx = next_prim_idx;
-       return 0;
+       clear_bit( 0, &primary->wrapped );
+       DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
 }
 
-/* More dynamic performance decisions */
-static inline int mga_decide_to_fire(drm_device_t *dev)
+
+/* ================================================================
+ * Freelist management
+ */
+
+#define MGA_BUFFER_USED                ~0
+#define MGA_BUFFER_FREE                0
+
+#if MGA_FREELIST_DEBUG
+static void mga_freelist_print( drm_device_t *dev )
 {
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_freelist_t *entry;
+
+       DRM_INFO( "\n" );
+       DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
+                 dev_priv->sarea_priv->last_dispatch,
+                 (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) -
+                                dev_priv->primary->offset) );
+       DRM_INFO( "current freelist:\n" );
+
+       for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
+               DRM_INFO( "   %p   idx=%2d  age=0x%x 0x%06lx\n",
+                         entry, entry->buf->idx, entry->age.head,
+                         entry->age.head - dev_priv->primary->offset );
+       }
+       DRM_INFO( "\n" );
+}
+#endif
 
-       if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
-               return 1;
-       }
+static int mga_freelist_init( drm_device_t *dev, drm_mga_private_t *dev_priv )
+{
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_t *buf;
+       drm_mga_buf_priv_t *buf_priv;
+       drm_mga_freelist_t *entry;
+       int i;
+       DRM_DEBUG( "%s: count=%d\n",
+                  __FUNCTION__, dma->buf_count );
 
-       if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
-           dev_priv->next_prim->num_dwords) {
-               return 1;
-       }
+       dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
+                                    DRM_MEM_DRIVER );
+       if ( dev_priv->head == NULL )
+               return -ENOMEM;
 
-       if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
-           dev_priv->next_prim->num_dwords) {
-               return 1;
-       }
+       memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) );
+       SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 );
 
-       if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
-               if(test_bit(MGA_BUF_SWAP_PENDING,
-                           &dev_priv->next_prim->buffer_status)) {
-                       return 1;
-               }
-       }
+       for ( i = 0 ; i < dma->buf_count ; i++ ) {
+               buf = dma->buflist[i];
+               buf_priv = buf->dev_private;
 
-       if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
-               if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
-                       return 1;
-               }
-       }
+               entry = DRM(alloc)( sizeof(drm_mga_freelist_t),
+                                   DRM_MEM_DRIVER );
+               if ( entry == NULL )
+                       return -ENOMEM;
 
-       if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
-               if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
-                       return 1;
-               }
+               memset( entry, 0, sizeof(drm_mga_freelist_t) );
+
+               entry->next = dev_priv->head->next;
+               entry->prev = dev_priv->head;
+               SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
+               entry->buf = buf;
+
+               if ( dev_priv->head->next != NULL )
+                       dev_priv->head->next->prev = entry;
+               if ( entry->next == NULL )
+                       dev_priv->tail = entry;
+
+               buf_priv->list_entry = entry;
+               buf_priv->discard = 0;
+               buf_priv->dispatched = 0;
+
+               dev_priv->head->next = entry;
        }
 
-       return 0;
+       return 0;
 }
 
-int mga_dma_schedule(drm_device_t *dev, int locked)
+static void mga_freelist_cleanup( drm_device_t *dev )
 {
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       int               retval    = 0;
-
-       if (!dev_priv) return -EBUSY;
-       
-       if (test_and_set_bit(0, &dev->dma_flag)) {
-               retval = -EBUSY;
-               goto sch_out_wakeup;
-       }
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_freelist_t *entry;
+       drm_mga_freelist_t *next;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
-          test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
-          test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
-               locked = 1;
+       entry = dev_priv->head;
+       while ( entry ) {
+               next = entry->next;
+               DRM(free)( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
+               entry = next;
        }
 
-       if (!locked &&
-           !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
-               clear_bit(0, &dev->dma_flag);
-               retval = -EBUSY;
-               goto sch_out_wakeup;
-       }
+       dev_priv->head = dev_priv->tail = NULL;
+}
 
-       if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
-               /* Fire dma buffer */
-               if(mga_decide_to_fire(dev)) {
-                       clear_bit(MGA_BUF_FORCE_FIRE,
-                                 &dev_priv->next_prim->buffer_status);
-                       if(dev_priv->current_prim == dev_priv->next_prim) {
-                               /* Schedule overflow for a later time */
-                               set_bit(MGA_BUF_NEEDS_OVERFLOW,
-                                       &dev_priv->next_prim->buffer_status);
-                       }
-                       mga_fire_primary(dev, dev_priv->next_prim);
-               } else {
-                       clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-               }
-       }
+#if 0
+/* FIXME: Still needed?
+ */
+static void mga_freelist_reset( drm_device_t *dev )
+{
+       drm_device_dma_t *dma = dev->dma;
+       drm_buf_t *buf;
+       drm_mga_buf_priv_t *buf_priv;
+       int i;
 
-       if (!locked) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
+       for ( i = 0 ; i < dma->buf_count ; i++ ) {
+               buf = dma->buflist[i];
+               buf_priv = buf->dev_private;
+               SET_AGE( &buf_priv->list_entry->age,
+                        MGA_BUFFER_FREE, 0 );
        }
+}
+#endif
+
+static drm_buf_t *mga_freelist_get( drm_device_t *dev )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_freelist_t *next;
+       drm_mga_freelist_t *prev;
+       drm_mga_freelist_t *tail = dev_priv->tail;
+       u32 head, wrap;
+       DRM_DEBUG( "%s:\n", __FUNCTION__ );
 
-       clear_bit(0, &dev->dma_flag);
+       head = MGA_READ( MGA_PRIMADDRESS );
+       wrap = dev_priv->sarea_priv->last_wrap;
 
-sch_out_wakeup:
-       if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
-          atomic_read(&dev_priv->pending_bufs) == 0) {
-               /* Everything has been processed by the hardware */
-               clear_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
-               wake_up_interruptible(&dev_priv->flush_queue);
-       }
+       DRM_DEBUG( "   tail=0x%06lx %d\n",
+                  tail->age.head ?
+                  tail->age.head - dev_priv->primary->offset : 0,
+                  tail->age.wrap );
+       DRM_DEBUG( "   head=0x%06lx %d\n",
+                  head - dev_priv->primary->offset, wrap );
 
-       if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)
-          && dev_priv->tail->age < dev_priv->last_prim_age)
-               wake_up_interruptible(&dev_priv->buf_queue);
+       if ( TEST_AGE( &tail->age, head, wrap ) ) {
+               prev = dev_priv->tail->prev;
+               next = dev_priv->tail;
+               prev->next = NULL;
+               next->prev = next->next = NULL;
+               dev_priv->tail = prev;
+               SET_AGE( &next->age, MGA_BUFFER_USED, 0 );
+               return next->buf;
+       }
 
-       return retval;
+       DRM_DEBUG( "returning NULL!\n" );
+       return NULL;
 }
 
-static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
+int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf )
 {
-       drm_device_t     *dev = (drm_device_t *)device;
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       drm_mga_prim_buf_t *last_prim_buffer;
-
-       atomic_inc(&dev->total_irq);
-       if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
-       MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
-       last_prim_buffer = dev_priv->last_prim;
-       last_prim_buffer->num_dwords = 0;
-       last_prim_buffer->sec_used = 0;
-       dev_priv->sarea_priv->last_dispatch =
-               dev_priv->last_prim_age = last_prim_buffer->prim_age;
-       clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
-       clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
-       clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-       atomic_dec(&dev_priv->pending_bufs);
-       queue_task(&dev->tq, &tq_immediate);
-       mark_bh(IMMEDIATE_BH);
-       wake_up_interruptible(&dev_priv->wait_queue);
-}
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+       drm_mga_freelist_t *head, *entry, *prev;
 
-static void mga_dma_task_queue(void *device)
-{
-       mga_dma_schedule((drm_device_t *)device, 0);
+       DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n",
+                  __FUNCTION__,
+                  buf_priv->list_entry->age.head -
+                  dev_priv->primary->offset,
+                  buf_priv->list_entry->age.wrap );
+
+       entry = buf_priv->list_entry;
+       head = dev_priv->head;
+
+       if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
+               SET_AGE( &entry->age, MGA_BUFFER_FREE, 0 );
+               prev = dev_priv->tail;
+               prev->next = entry;
+               entry->prev = prev;
+               entry->next = NULL;
+       } else {
+               prev = head->next;
+               head->next = entry;
+               prev->prev = entry;
+               entry->prev = head;
+               entry->next = prev;
+       }
+
+       return 0;
 }
 
-int mga_dma_cleanup(drm_device_t *dev)
+
+/* ================================================================
+ * DMA initialization, cleanup
+ */
+
+static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
 {
-       if(dev->dev_private) {
-               drm_mga_private_t *dev_priv =
-                       (drm_mga_private_t *) dev->dev_private;
+       drm_mga_private_t *dev_priv;
+       struct list_head *list;
+       int ret;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-               if (dev->irq) mga_flush_queue(dev);
-               mga_dma_quiescent(dev);
+       dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
+       if ( !dev_priv )
+               return -ENOMEM;
 
-               if(dev_priv->ioremap) {
-                       int temp = (dev_priv->warp_ucode_size +
-                                   dev_priv->primary_size +
-                                   PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
+       memset( dev_priv, 0, sizeof(drm_mga_private_t) );
 
-                       drm_ioremapfree((void *) dev_priv->ioremap, temp);
-               }
-               if(dev_priv->status_page != NULL) {
-                       iounmap(dev_priv->status_page);
-               }
-               if(dev_priv->real_status_page != 0UL) {
-                       mga_free_page(dev, dev_priv->real_status_page);
-               }
-               if(dev_priv->prim_bufs != NULL) {
-                       int i;
-                       for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
-                               if(dev_priv->prim_bufs[i] != NULL) {
-                                       drm_free(dev_priv->prim_bufs[i],
-                                                sizeof(drm_mga_prim_buf_t),
-                                                DRM_MEM_DRIVER);
-                               }
-                       }
-                       drm_free(dev_priv->prim_bufs, sizeof(void *) *
-                                (MGA_NUM_PRIM_BUFS + 1),
-                                DRM_MEM_DRIVER);
-               }
-               if(dev_priv->head != NULL) {
-                       mga_freelist_cleanup(dev);
-               }
+       dev_priv->chipset = init->chipset;
 
+       dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
 
-               drm_free(dev->dev_private, sizeof(drm_mga_private_t),
-                        DRM_MEM_DRIVER);
-               dev->dev_private = NULL;
+       if ( init->sgram ) {
+               dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
+       } else {
+               dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
        }
+       dev_priv->maccess       = init->maccess;
 
-       return 0;
-}
+       dev_priv->fb_cpp        = init->fb_cpp;
+       dev_priv->front_offset  = init->front_offset;
+       dev_priv->front_pitch   = init->front_pitch;
+       dev_priv->back_offset   = init->back_offset;
+       dev_priv->back_pitch    = init->back_pitch;
 
-static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
-       drm_mga_private_t *dev_priv;
-       drm_map_t *sarea_map = NULL;
+       dev_priv->depth_cpp     = init->depth_cpp;
+       dev_priv->depth_offset  = init->depth_offset;
+       dev_priv->depth_pitch   = init->depth_pitch;
 
-       dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
-       if(dev_priv == NULL) return -ENOMEM;
-       dev->dev_private = (void *) dev_priv;
+       /* FIXME: Need to support AGP textures...
+        */
+       dev_priv->texture_offset = init->texture_offset[0];
+       dev_priv->texture_size = init->texture_size[0];
+
+       list_for_each( list, &dev->maplist->head ) {
+               drm_map_list_t *entry = (drm_map_list_t *)list;
+               if ( entry->map &&
+                    entry->map->type == _DRM_SHM &&
+                    (entry->map->flags & _DRM_CONTAINS_LOCK) ) {
+                       dev_priv->sarea = entry->map;
+                       break;
+               }
+       }
+       if(!dev_priv->sarea) {
+               DRM_ERROR( "failed to find sarea!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
 
-       memset(dev_priv, 0, sizeof(drm_mga_private_t));
+       DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
+       if(!dev_priv->fb) {
+               DRM_ERROR( "failed to find framebuffer!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+       if(!dev_priv->mmio) {
+               DRM_ERROR( "failed to find mmio region!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->status, init->status_offset );
+       if(!dev_priv->status) {
+               DRM_ERROR( "failed to find status page!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
 
-       if((init->reserved_map_idx >= dev->map_count) ||
-          (init->buffer_map_idx >= dev->map_count)) {
-               mga_dma_cleanup(dev);
+       DRM_FIND_MAP( dev_priv->warp, init->warp_offset );
+       if(!dev_priv->warp) {
+               DRM_ERROR( "failed to find warp microcode region!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->primary, init->primary_offset );
+       if(!dev_priv->primary) {
+               DRM_ERROR( "failed to find primary dma region!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+       if(!dev_priv->buffers) {
+               DRM_ERROR( "failed to find dma buffer region!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
                return -EINVAL;
        }
 
-       dev_priv->reserved_map_idx = init->reserved_map_idx;
-       dev_priv->buffer_map_idx = init->buffer_map_idx;
-       sarea_map = dev->maplist[0];
-       dev_priv->sarea_priv = (drm_mga_sarea_t *)
-               ((u8 *)sarea_map->handle +
-                init->sarea_priv_offset);
+       dev_priv->sarea_priv =
+               (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
+                                   init->sarea_priv_offset);
 
-       /* Scale primary size to the next page */
-       dev_priv->chipset = init->chipset;
-       dev_priv->frontOffset = init->frontOffset;
-       dev_priv->backOffset = init->backOffset;
-       dev_priv->depthOffset = init->depthOffset;
-       dev_priv->textureOffset = init->textureOffset;
-       dev_priv->textureSize = init->textureSize;
-       dev_priv->cpp = init->cpp;
-       dev_priv->sgram = init->sgram;
-       dev_priv->stride = init->stride;
-
-       dev_priv->mAccess = init->mAccess;
-       init_waitqueue_head(&dev_priv->flush_queue);
-       init_waitqueue_head(&dev_priv->buf_queue);
-       dev_priv->WarpPipe = 0xff000000;
-       dev_priv->vertexsize = 0;
-
-       DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n",
-                 dev_priv->chipset, dev_priv->warp_ucode_size,
-                 dev_priv->backOffset, dev_priv->depthOffset);
-       DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n",
-                 dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
-                 dev_priv->mAccess);
-
-       memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
-              sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
-
-       if(mga_init_primary_bufs(dev, init) != 0) {
-               DRM_ERROR("Can not initialize primary buffers\n");
-               mga_dma_cleanup(dev);
+       DRM_IOREMAP( dev_priv->warp );
+       DRM_IOREMAP( dev_priv->primary );
+       DRM_IOREMAP( dev_priv->buffers );
+
+       if(!dev_priv->warp->handle ||
+          !dev_priv->primary->handle ||
+          !dev_priv->buffers->handle ) {
+               DRM_ERROR( "failed to ioremap agp regions!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
                return -ENOMEM;
        }
-       dev_priv->real_status_page = mga_alloc_page(dev);
-       if(dev_priv->real_status_page == 0UL) {
-               mga_dma_cleanup(dev);
-               DRM_ERROR("Can not allocate status page\n");
-               return -ENOMEM;
+
+       ret = mga_warp_install_microcode( dev_priv );
+       if ( ret < 0 ) {
+               DRM_ERROR( "failed to install WARP ucode!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return ret;
        }
 
-       dev_priv->status_page =
-               ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
-                               PAGE_SIZE);
+       ret = mga_warp_init( dev_priv );
+       if ( ret < 0 ) {
+               DRM_ERROR( "failed to init WARP engine!\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
+               return ret;
+       }
+
+       dev_priv->prim.status = (u32 *)dev_priv->status->handle;
+
+       mga_do_wait_for_idle( dev_priv );
 
-       if(dev_priv->status_page == NULL) {
-               mga_dma_cleanup(dev);
-               DRM_ERROR("Can not remap status page\n");
+       /* Init the primary DMA registers.
+        */
+       MGA_WRITE( MGA_PRIMADDRESS,
+                  dev_priv->primary->offset | MGA_DMA_GENERAL );
+#if 0
+       MGA_WRITE( MGA_PRIMPTR,
+                  virt_to_bus((void *)dev_priv->prim.status) |
+                  MGA_PRIMPTREN0 |     /* Soft trap, SECEND, SETUPEND */
+                  MGA_PRIMPTREN1 );    /* DWGSYNC */
+#endif
+
+       dev_priv->prim.start = (u8 *)dev_priv->primary->handle;
+       dev_priv->prim.end = ((u8 *)dev_priv->primary->handle
+                             + dev_priv->primary->size);
+       dev_priv->prim.size = dev_priv->primary->size;
+
+       dev_priv->prim.tail = 0;
+       dev_priv->prim.space = dev_priv->prim.size;
+       dev_priv->prim.wrapped = 0;
+
+       dev_priv->prim.last_flush = 0;
+       dev_priv->prim.last_wrap = 0;
+
+       dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;
+
+       spin_lock_init( &dev_priv->prim.list_lock );
+
+       dev_priv->prim.status[0] = dev_priv->primary->offset;
+       dev_priv->prim.status[1] = 0;
+
+       dev_priv->sarea_priv->last_wrap = 0;
+       dev_priv->sarea_priv->last_frame.head = 0;
+       dev_priv->sarea_priv->last_frame.wrap = 0;
+
+       if ( mga_freelist_init( dev, dev_priv ) < 0 ) {
+               DRM_ERROR( "could not initialize freelist\n" );
+               /* Assign dev_private so we can do cleanup. */
+               dev->dev_private = (void *)dev_priv;
+               mga_do_cleanup_dma( dev );
                return -ENOMEM;
        }
 
-       /* Write status page when secend or softrap occurs */
-       MGA_WRITE(MGAREG_PRIMPTR,
-                 virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
-
+       /* Make dev_private visable to others. */
+       dev->dev_private = (void *)dev_priv;
+       return 0;
+}
 
-       /* Private is now filled in, initialize the hardware */
-       {
-               PRIMLOCALS;
-               PRIMGETPTR( dev_priv );
+int mga_do_cleanup_dma( drm_device_t *dev )
+{
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
-               PRIMOUTREG(MGAREG_SOFTRAP, 0);
-               /* Poll for the first buffer to insure that
-                * the status register will be correct
-                */
+       if ( dev->dev_private ) {
+               drm_mga_private_t *dev_priv = dev->dev_private;
 
-               mga_flush_write_combine();
-               MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
+               DRM_IOREMAPFREE( dev_priv->warp );
+               DRM_IOREMAPFREE( dev_priv->primary );
+               DRM_IOREMAPFREE( dev_priv->buffers );
 
-               MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
-                                          PDEA_pagpxfer_enable));
+               if ( dev_priv->head != NULL ) {
+                       mga_freelist_cleanup( dev );
+               }
 
-               while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
+               DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),
+                          DRM_MEM_DRIVER );
+               dev->dev_private = NULL;
        }
 
-       if(mga_freelist_init(dev) != 0) {
-               DRM_ERROR("Could not initialize freelist\n");
-               mga_dma_cleanup(dev);
-               return -ENOMEM;
-       }
        return 0;
 }
 
-int mga_dma_init(struct inode *inode, struct file *filp,
-                unsigned int cmd, unsigned long arg)
+int mga_dma_init( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
        drm_mga_init_t init;
 
-       if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
+       if ( copy_from_user( &init, (drm_mga_init_t *)arg, sizeof(init) ) )
                return -EFAULT;
 
-       switch(init.func) {
+       switch ( init.func ) {
        case MGA_INIT_DMA:
-               return mga_dma_initialize(dev, &init);
+               return mga_do_init_dma( dev, &init );
        case MGA_CLEANUP_DMA:
-               return mga_dma_cleanup(dev);
+               return mga_do_cleanup_dma( dev );
        }
 
        return -EINVAL;
 }
 
-int mga_irq_install(drm_device_t *dev, int irq)
-{
-       int retcode;
-
-       if (!irq)     return -EINVAL;
 
-       down(&dev->struct_sem);
-       if (dev->irq) {
-               up(&dev->struct_sem);
-               return -EBUSY;
-       }
-       dev->irq = irq;
-       up(&dev->struct_sem);
-
-       DRM_DEBUG("install irq handler %d\n", irq);
-
-       dev->context_flag     = 0;
-       dev->interrupt_flag   = 0;
-       dev->dma_flag         = 0;
-       dev->dma->next_buffer = NULL;
-       dev->dma->next_queue  = NULL;
-       dev->dma->this_buffer = NULL;
-       INIT_LIST_HEAD(&dev->tq.list);
-       dev->tq.sync          = 0;
-       dev->tq.routine       = mga_dma_task_queue;
-       dev->tq.data          = dev;
-
-                               /* Before installing handler */
-       MGA_WRITE(MGAREG_IEN, 0);
-                               /* Install handler */
-       if ((retcode = request_irq(dev->irq,
-                                  mga_dma_service,
-                                  SA_SHIRQ,
-                                  dev->devname,
-                                  dev))) {
-               down(&dev->struct_sem);
-               dev->irq = 0;
-               up(&dev->struct_sem);
-               return retcode;
-       }
-                               /* After installing handler */
-       MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
-       MGA_WRITE(MGAREG_IEN, 0x00000001);
-       return 0;
-}
+/* ================================================================
+ * Primary DMA stream management
+ */
 
-int mga_irq_uninstall(drm_device_t *dev)
+int mga_dma_flush( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
 {
-       int irq;
-
-       down(&dev->struct_sem);
-       irq      = dev->irq;
-       dev->irq = 0;
-       up(&dev->struct_sem);
-
-       if (!irq) return -EINVAL;
-       DRM_DEBUG("remove irq handler %d\n", irq);
-       MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
-       MGA_WRITE(MGAREG_IEN, 0);
-       free_irq(irq, dev);
-       return 0;
-}
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+       drm_lock_t lock;
 
-int mga_control(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_control_t   ctl;
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
+       if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
                return -EFAULT;
 
-       switch (ctl.func) {
-       case DRM_INST_HANDLER:
-               return mga_irq_install(dev, ctl.irq);
-       case DRM_UNINST_HANDLER:
-               return mga_irq_uninstall(dev);
-       default:
-               return -EINVAL;
+       DRM_DEBUG( "%s: %s%s%s\n",
+                  __FUNCTION__,
+                  (lock.flags & _DRM_LOCK_FLUSH) ?     "flush, " : "",
+                  (lock.flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
+                  (lock.flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "" );
+
+       WRAP_WAIT_WITH_RETURN( dev_priv );
+
+       if ( lock.flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL) ) {
+               mga_do_dma_flush( dev_priv );
        }
-}
 
-static int mga_flush_queue(drm_device_t *dev)
-{
-       DECLARE_WAITQUEUE(entry, current);
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
-       int ret = 0;
-
-       if(!dev_priv) return 0;
-
-       if(dev_priv->next_prim->num_dwords != 0) {
-               add_wait_queue(&dev_priv->flush_queue, &entry);
-               if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status)) 
-                       DRM_ERROR("Incorrect mga_flush_queue logic\n");
-               set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
-               mga_dma_schedule(dev, 0);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!test_bit(MGA_IN_FLUSH,
-                                     &dev_priv->dispatch_status))
-                               break;
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -EINTR; /* Can't restart */
-                               clear_bit(MGA_IN_FLUSH,
-                                         &dev_priv->dispatch_status);
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev_priv->flush_queue, &entry);
+       if ( lock.flags & _DRM_LOCK_QUIESCENT ) {
+#if MGA_DMA_DEBUG
+               int ret = mga_do_wait_for_idle( dev_priv );
+               if ( ret < 0 )
+                       DRM_INFO( __FUNCTION__": -EBUSY\n" );
+               return ret;
+#else
+               return mga_do_wait_for_idle( dev_priv );
+#endif
+       } else {
+               return 0;
        }
-       return ret;
 }
 
-/* Must be called with the lock held */
-void mga_reclaim_buffers(drm_device_t *dev, pid_t pid)
+int mga_dma_reset( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
 {
-       drm_device_dma_t *dma = dev->dma;
-       int              i;
-
-       if (!dma) return;
-       if(dev->dev_private == NULL) return;
-       if(dma->buflist == NULL) return;
-
-       DRM_DEBUG("buf_count=%d\n", dma->buf_count);
-       
-        mga_flush_queue(dev);
-
-       for (i = 0; i < dma->buf_count; i++) {
-               drm_buf_t *buf = dma->buflist[ i ];
-               drm_mga_buf_priv_t *buf_priv = buf->dev_private;
-
-               /* Only buffers that need to get reclaimed ever
-                * get set to free
-                */
-               if (buf->pid == pid  && buf_priv) {
-                       if(buf_priv->my_freelist->age == MGA_BUF_USED)
-                               buf_priv->my_freelist->age = MGA_BUF_FREE;
-               }
-       }
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+
+       LOCK_TEST_WITH_RETURN( dev );
+
+       return mga_do_dma_reset( dev_priv );
 }
 
-int mga_lock(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       DECLARE_WAITQUEUE(entry, current);
-       int               ret   = 0;
-       drm_lock_t        lock;
 
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
+/* ================================================================
+ * DMA buffer management
+ */
 
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
+static int mga_dma_get_buffers( drm_device_t *dev, drm_dma_t *d )
+{
+       drm_buf_t *buf;
+       int i;
 
-       if (lock.context < 0) return -EINVAL;
+       for ( i = d->granted_count ; i < d->request_count ; i++ ) {
+               buf = mga_freelist_get( dev );
+               if ( !buf ) return -EAGAIN;
 
-       /* Only one queue:
-        */
+               buf->pid = current->pid;
 
-       if (!ret) {
-               add_wait_queue(&dev->lock.lock_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!dev->lock.hw_lock) {
-                               /* Device has been unregistered */
-                               ret = -EINTR;
-                               break;
-                       }
-                       if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                         lock.context)) {
-                               dev->lock.pid       = current->pid;
-                               dev->lock.lock_time = jiffies;
-                               atomic_inc(&dev->total_locks);
-                               break;  /* Got lock */
-                       }
-
-                               /* Contention */
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->lock.lock_queue, &entry);
-       }
+               if ( copy_to_user( &d->request_indices[i],
+                                  &buf->idx, sizeof(buf->idx) ) )
+                       return -EFAULT;
+               if ( copy_to_user( &d->request_sizes[i],
+                                  &buf->total, sizeof(buf->total) ) )
+                       return -EFAULT;
 
-       if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
-               if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                  DRM_DEBUG("_DRM_LOCK_QUIESCENT\n");
-                  mga_flush_queue(dev);
-                  mga_dma_quiescent(dev);
-               }
+               d->granted_count++;
        }
-
-       if (ret) DRM_DEBUG("%d %s\n", lock.context,
-                          ret ? "interrupted" : "has lock");
-       return ret;
+       return 0;
 }
 
-int mga_flush_ioctl(struct inode *inode, struct file *filp,
-                   unsigned int cmd, unsigned long arg)
+int mga_dma_buffers( struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg )
 {
-               drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+       drm_device_dma_t *dma = dev->dma;
+       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+       drm_dma_t d;
+       int ret = 0;
+
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
+       if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
                return -EFAULT;
 
-       if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("lock not held\n");
+       /* Please don't send us buffers.
+        */
+       if ( d.send_count != 0 ) {
+               DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
+                          current->pid, d.send_count );
+               return -EINVAL;
+       }
+
+       /* We'll send you buffers.
+        */
+       if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
+               DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
+                          current->pid, d.request_count, dma->buf_count );
                return -EINVAL;
        }
 
-       if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
-               drm_mga_prim_buf_t *temp_buf;
+       WRAP_TEST_WITH_RETURN( dev_priv );
 
-               temp_buf = dev_priv->current_prim;
+       d.granted_count = 0;
 
-               if(temp_buf && temp_buf->num_dwords) {
-                       set_bit(MGA_BUF_FORCE_FIRE, &temp_buf->buffer_status);
-                       mga_advance_primary(dev);
-               }
-               mga_dma_schedule(dev, 1);
-       }
-       if(lock.flags & _DRM_LOCK_QUIESCENT) {
-               mga_flush_queue(dev);
-               mga_dma_quiescent(dev);
+       if ( d.request_count ) {
+               ret = mga_dma_get_buffers( dev, &d );
        }
 
-       return 0;
+       if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
+               return -EFAULT;
+
+       return ret;
 }
index 52cf77665aa14825c07992b7dc12067c22e8bf3e..4af2ca2e843020eba51636a015b4058409ca54ee 100644 (file)
  * 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
+ * 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.
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Jeff Hartmann <jhartmann@valinux.com>
- *          Keith Whitwell <keithw@valinux.com>
+ * Authors:
+ *    Jeff Hartmann <jhartmann@valinux.com>
+ *    Keith Whitwell <keithw@valinux.com>
  *
+ * Rewritten by:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
-#ifndef _MGA_DRM_H_
-#define _MGA_DRM_H_
+#ifndef __MGA_DRM_H__
+#define __MGA_DRM_H__
 
 /* WARNING: If you change any of these defines, make sure to change the
- * defines in the Xserver file (xf86drmMga.h)
- */
-#ifndef _MGA_DEFINES_
-#define _MGA_DEFINES_
-
-#define MGA_F  0x1             /* fog */
-#define MGA_A  0x2             /* alpha */
-#define MGA_S  0x4             /* specular */
-#define MGA_T2 0x8             /* multitexture */
-
-#define MGA_WARP_TGZ            0
-#define MGA_WARP_TGZF           (MGA_F)
-#define MGA_WARP_TGZA           (MGA_A)
-#define MGA_WARP_TGZAF          (MGA_F|MGA_A)
-#define MGA_WARP_TGZS           (MGA_S)
-#define MGA_WARP_TGZSF          (MGA_S|MGA_F)
-#define MGA_WARP_TGZSA          (MGA_S|MGA_A)
-#define MGA_WARP_TGZSAF         (MGA_S|MGA_F|MGA_A)
-#define MGA_WARP_T2GZ           (MGA_T2)
-#define MGA_WARP_T2GZF          (MGA_T2|MGA_F)
-#define MGA_WARP_T2GZA          (MGA_T2|MGA_A)
-#define MGA_WARP_T2GZAF         (MGA_T2|MGA_A|MGA_F)
-#define MGA_WARP_T2GZS          (MGA_T2|MGA_S)
-#define MGA_WARP_T2GZSF         (MGA_T2|MGA_S|MGA_F)
-#define MGA_WARP_T2GZSA         (MGA_T2|MGA_S|MGA_A)
-#define MGA_WARP_T2GZSAF        (MGA_T2|MGA_S|MGA_F|MGA_A)
-
-#define MGA_MAX_G400_PIPES 16
-#define MGA_MAX_G200_PIPES  8  /* no multitex */
-#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
-
-#define MGA_CARD_TYPE_G200 1
-#define MGA_CARD_TYPE_G400 2
-
-#define MGA_FRONT   0x1
-#define MGA_BACK    0x2
-#define MGA_DEPTH   0x4
-
-/* 3d state excluding texture units:
+ * defines in the Xserver file (mga_sarea.h)
  */
-#define MGA_CTXREG_DSTORG     0        /* validated */
-#define MGA_CTXREG_MACCESS    1        
-#define MGA_CTXREG_PLNWT      2        
-#define MGA_CTXREG_DWGCTL     3        
-#define MGA_CTXREG_ALPHACTRL  4
-#define MGA_CTXREG_FOGCOLOR   5
-#define MGA_CTXREG_WFLAG      6
-#define MGA_CTXREG_TDUAL0     7
-#define MGA_CTXREG_TDUAL1     8
-#define MGA_CTXREG_FCOL       9
-#define MGA_CTXREG_STENCIL    10
-#define MGA_CTXREG_STENCILCTL 11
-#define MGA_CTX_SETUP_SIZE    12
-
-/* 2d state
- */
-#define MGA_2DREG_PITCH        0
-#define MGA_2D_SETUP_SIZE      1
+#ifndef __MGA_SAREA_DEFINES__
+#define __MGA_SAREA_DEFINES__
 
-/* Each texture unit has a state:
+/* WARP pipe flags
  */
-#define MGA_TEXREG_CTL        0
-#define MGA_TEXREG_CTL2       1
-#define MGA_TEXREG_FILTER     2
-#define MGA_TEXREG_BORDERCOL  3
-#define MGA_TEXREG_ORG        4 /* validated */
-#define MGA_TEXREG_ORG1       5
-#define MGA_TEXREG_ORG2       6
-#define MGA_TEXREG_ORG3       7
-#define MGA_TEXREG_ORG4       8
-#define MGA_TEXREG_WIDTH      9
-#define MGA_TEXREG_HEIGHT     10
-#define MGA_TEX_SETUP_SIZE    11
+#define MGA_F                  0x1             /* fog */
+#define MGA_A                  0x2             /* alpha */
+#define MGA_S                  0x4             /* specular */
+#define MGA_T2                 0x8             /* multitexture */
+
+#define MGA_WARP_TGZ           0
+#define MGA_WARP_TGZF          (MGA_F)
+#define MGA_WARP_TGZA          (MGA_A)
+#define MGA_WARP_TGZAF         (MGA_F|MGA_A)
+#define MGA_WARP_TGZS          (MGA_S)
+#define MGA_WARP_TGZSF         (MGA_S|MGA_F)
+#define MGA_WARP_TGZSA         (MGA_S|MGA_A)
+#define MGA_WARP_TGZSAF                (MGA_S|MGA_F|MGA_A)
+#define MGA_WARP_T2GZ          (MGA_T2)
+#define MGA_WARP_T2GZF         (MGA_T2|MGA_F)
+#define MGA_WARP_T2GZA         (MGA_T2|MGA_A)
+#define MGA_WARP_T2GZAF                (MGA_T2|MGA_A|MGA_F)
+#define MGA_WARP_T2GZS         (MGA_T2|MGA_S)
+#define MGA_WARP_T2GZSF                (MGA_T2|MGA_S|MGA_F)
+#define MGA_WARP_T2GZSA                (MGA_T2|MGA_S|MGA_A)
+#define MGA_WARP_T2GZSAF       (MGA_T2|MGA_S|MGA_F|MGA_A)
+
+#define MGA_MAX_G200_PIPES     8               /* no multitex */
+#define MGA_MAX_G400_PIPES     16
+#define MGA_MAX_WARP_PIPES     MGA_MAX_G400_PIPES
+#define MGA_WARP_UCODE_SIZE    32768           /* in bytes */
+
+#define MGA_CARD_TYPE_G200     1
+#define MGA_CARD_TYPE_G400     2
+
+
+#define MGA_FRONT              0x1
+#define MGA_BACK               0x2
+#define MGA_DEPTH              0x4
 
 /* What needs to be changed for the current vertex dma buffer?
  */
-#define MGA_UPLOAD_CTX        0x1
-#define MGA_UPLOAD_TEX0       0x2
-#define MGA_UPLOAD_TEX1       0x4
-#define MGA_UPLOAD_PIPE       0x8
-#define MGA_UPLOAD_TEX0IMAGE  0x10 /* handled client-side */
-#define MGA_UPLOAD_TEX1IMAGE  0x20 /* handled client-side */
-#define MGA_UPLOAD_2D        0x40
-#define MGA_WAIT_AGE          0x80 /* handled client-side */
-#define MGA_UPLOAD_CLIPRECTS  0x100 /* handled client-side */
-#define MGA_DMA_FLUSH        0x200 /* set when someone gets the lock
-                                       quiescent */
+#define MGA_UPLOAD_CONTEXT     0x1
+#define MGA_UPLOAD_TEX0                0x2
+#define MGA_UPLOAD_TEX1                0x4
+#define MGA_UPLOAD_PIPE                0x8
+#define MGA_UPLOAD_TEX0IMAGE   0x10 /* handled client-side */
+#define MGA_UPLOAD_TEX1IMAGE   0x20 /* handled client-side */
+#define MGA_UPLOAD_2D          0x40
+#define MGA_WAIT_AGE           0x80 /* handled client-side */
+#define MGA_UPLOAD_CLIPRECTS   0x100 /* handled client-side */
+#if 0
+#define MGA_DMA_FLUSH          0x200 /* set when someone gets the lock
+                                        quiescent */
+#endif
 
 /* 32 buffers of 64k each, total 2 meg.
  */
-#define MGA_DMA_BUF_ORDER     16
-#define MGA_DMA_BUF_SZ        (1<<MGA_DMA_BUF_ORDER)
-#define MGA_DMA_BUF_NR        31
+#define MGA_BUFFER_SIZE                (1 << 16)
+#define MGA_NUM_BUFFERS                128
 
 /* Keep these small for testing.
  */
-#define MGA_NR_SAREA_CLIPRECTS 8
+#define MGA_NR_SAREA_CLIPRECTS 8
 
 /* 2 heaps (1 for card, 1 for agp), each divided into upto 128
- * regions, subject to a minimum region size of (1<<16) == 64k. 
+ * regions, subject to a minimum region size of (1<<16) == 64k.
  *
  * Clients may subdivide regions internally, but when sharing between
- * clients, the region size is the minimum granularity. 
+ * clients, the region size is the minimum granularity.
  */
 
-#define MGA_CARD_HEAP 0
-#define MGA_AGP_HEAP  1
-#define MGA_NR_TEX_HEAPS 2
-#define MGA_NR_TEX_REGIONS 16
-#define MGA_LOG_MIN_TEX_REGION_SIZE 16
-#endif
+#define MGA_CARD_HEAP                  0
+#define MGA_AGP_HEAP                   1
+#define MGA_NR_TEX_HEAPS               2
+#define MGA_NR_TEX_REGIONS             16
+#define MGA_LOG_MIN_TEX_REGION_SIZE    16
 
-typedef struct _drm_mga_warp_index {
-       int installed;
-       unsigned long phys_addr;
-       int size;
-} drm_mga_warp_index_t;
+#endif /* __MGA_SAREA_DEFINES__ */
 
-typedef struct drm_mga_init {
-       enum { 
-               MGA_INIT_DMA = 0x01,
-               MGA_CLEANUP_DMA = 0x02
-       } func;
-       int reserved_map_agpstart;
-       int reserved_map_idx;
-       int buffer_map_idx;
-       int sarea_priv_offset;
-       int primary_size;
-       int warp_ucode_size;
-       unsigned int frontOffset;
-       unsigned int backOffset;
-       unsigned int depthOffset;
-       unsigned int textureOffset;
-       unsigned int textureSize;
-        unsigned int agpTextureOffset;
-        unsigned int agpTextureSize;
-       unsigned int cpp;
-       unsigned int stride;
-       int sgram;
-       int chipset;
-       drm_mga_warp_index_t WarpIndex[MGA_MAX_WARP_PIPES];
-       unsigned int mAccess;
-} drm_mga_init_t;
 
-/* Warning: if you change the sarea structure, you must change the Xserver
- * structures as well */
+/* Setup registers for 3D context
+ */
+typedef struct {
+       unsigned int dstorg;
+       unsigned int maccess;
+       unsigned int plnwt;
+       unsigned int dwgctl;
+       unsigned int alphactrl;
+       unsigned int fogcolor;
+       unsigned int wflag;
+       unsigned int tdualstage0;
+       unsigned int tdualstage1;
+       unsigned int fcol;
+       unsigned int stencil;
+       unsigned int stencilctl;
+} drm_mga_context_regs_t;
+
+/* Setup registers for 2D, X server
+ */
+typedef struct {
+       unsigned int pitch;
+} drm_mga_server_regs_t;
 
-typedef struct _drm_mga_tex_region {
-       unsigned char next, prev;       
-       unsigned char in_use;   
-       unsigned int age;                       
-} drm_mga_tex_region_t;
+/* Setup registers for each texture unit
+ */
+typedef struct {
+       unsigned int texctl;
+       unsigned int texctl2;
+       unsigned int texfilter;
+       unsigned int texbordercol;
+       unsigned int texorg;
+       unsigned int texwidth;
+       unsigned int texheight;
+       unsigned int texorg1;
+       unsigned int texorg2;
+       unsigned int texorg3;
+       unsigned int texorg4;
+} drm_mga_texture_regs_t;
+
+/* General aging mechanism
+ */
+typedef struct {
+       unsigned int head;              /* Position of head pointer          */
+       unsigned int wrap;              /* Primary DMA wrap count            */
+} drm_mga_age_t;
 
 typedef struct _drm_mga_sarea {
        /* The channel for communication of state information to the kernel
         * on firing a vertex dma buffer.
         */
-       unsigned int ContextState[MGA_CTX_SETUP_SIZE];
-       unsigned int ServerState[MGA_2D_SETUP_SIZE];
-       unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
-       unsigned int WarpPipe;
+       drm_mga_context_regs_t context_state;
+       drm_mga_server_regs_t server_state;
+       drm_mga_texture_regs_t tex_state[2];
+       unsigned int warp_pipe;
        unsigned int dirty;
+       unsigned int vertsize;
 
-       unsigned int nbox;
+       /* The current cliprects, or a subset thereof.
+        */
        drm_clip_rect_t boxes[MGA_NR_SAREA_CLIPRECTS];
-
+       unsigned int nbox;
 
        /* Information about the most recently used 3d drawable.  The
-        * client fills in the req_* fields, the server fills in the 
+        * client fills in the req_* fields, the server fills in the
         * exported_ fields and puts the cliprects into boxes, above.
         *
         * The client clears the exported_drawable field before
@@ -210,65 +191,120 @@ typedef struct _drm_mga_sarea {
         unsigned int req_drawable;      /* the X drawable id */
        unsigned int req_draw_buffer;    /* MGA_FRONT or MGA_BACK */
 
-        unsigned int exported_drawable;         
-       unsigned int exported_index; 
-        unsigned int exported_stamp;   
-        unsigned int exported_buffers;  
+        unsigned int exported_drawable;
+       unsigned int exported_index;
+        unsigned int exported_stamp;
+        unsigned int exported_buffers;
         unsigned int exported_nfront;
         unsigned int exported_nback;
-       int exported_back_x, exported_front_x, exported_w;      
+       int exported_back_x, exported_front_x, exported_w;
        int exported_back_y, exported_front_y, exported_h;
        drm_clip_rect_t exported_boxes[MGA_NR_SAREA_CLIPRECTS];
-   
+
        /* Counters for aging textures and for client-side throttling.
         */
+       unsigned int status[4];
+       unsigned int last_wrap;
+
+       drm_mga_age_t last_frame;
         unsigned int last_enqueue;     /* last time a buffer was enqueued */
        unsigned int last_dispatch;     /* age of the most recently dispatched buffer */
        unsigned int last_quiescent;     /*  */
 
-
-       /* LRU lists for texture memory in agp space and on the card
+       /* LRU lists for texture memory in agp space and on the card.
         */
-       drm_mga_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
+       drm_tex_region_t texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS+1];
        unsigned int texAge[MGA_NR_TEX_HEAPS];
-       
+
        /* Mechanism to validate card state.
         */
        int ctxOwner;
-       int vertexsize;
-} drm_mga_sarea_t;     
+} drm_mga_sarea_t;
 
-/* Device specific ioctls:
+
+/* WARNING: If you change any of these defines, make sure to change the
+ * defines in the Xserver file (xf86drmMga.h)
  */
-typedef struct _drm_mga_clear {
+typedef struct _drm_mga_warp_index {
+       int installed;
+       unsigned long phys_addr;
+       int size;
+} drm_mga_warp_index_t;
+
+typedef struct drm_mga_init {
+       enum {
+               MGA_INIT_DMA    = 0x01,
+               MGA_CLEANUP_DMA = 0x02
+       } func;
+
+       unsigned long sarea_priv_offset;
+
+       int chipset;
+       int sgram;
+
+       unsigned int maccess;
+
+       unsigned int fb_cpp;
+       unsigned int front_offset, front_pitch;
+       unsigned int back_offset, back_pitch;
+
+       unsigned int depth_cpp;
+       unsigned int depth_offset, depth_pitch;
+
+       unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+       unsigned int texture_size[MGA_NR_TEX_HEAPS];
+
+       unsigned long fb_offset;
+       unsigned long mmio_offset;
+       unsigned long status_offset;
+       unsigned long warp_offset;
+       unsigned long primary_offset;
+       unsigned long buffers_offset;
+} drm_mga_init_t;
+
+typedef struct drm_mga_fullscreen {
+       enum {
+               MGA_INIT_FULLSCREEN    = 0x01,
+               MGA_CLEANUP_FULLSCREEN = 0x02
+       } func;
+} drm_mga_fullscreen_t;
+
+typedef struct drm_mga_clear {
+       unsigned int flags;
        unsigned int clear_color;
        unsigned int clear_depth;
-       unsigned int flags;
-       unsigned int clear_depth_mask;
-       unsigned int clear_color_mask;
+       unsigned int color_mask;
+       unsigned int depth_mask;
 } drm_mga_clear_t;
 
-typedef struct _drm_mga_swap {
-       int dummy;
-} drm_mga_swap_t;
+typedef struct drm_mga_vertex {
+       int idx;                        /* buffer to queue */
+       int used;                       /* bytes in use */
+       int discard;                    /* client finished with buffer?  */
+} drm_mga_vertex_t;
+
+typedef struct drm_mga_indices {
+       int idx;                        /* buffer to queue */
+       unsigned int start;
+       unsigned int end;
+       int discard;                    /* client finished with buffer?  */
+} drm_mga_indices_t;
 
-typedef struct _drm_mga_iload {
+typedef struct drm_mga_iload {
        int idx;
-       int length;
-       unsigned int destOrg;
+       unsigned int dstorg;
+       unsigned int length;
 } drm_mga_iload_t;
 
-typedef struct _drm_mga_vertex {
-       int idx;                /* buffer to queue */
-       int used;               /* bytes in use */
-       int discard;            /* client finished with buffer?  */
-} drm_mga_vertex_t;
-
-typedef struct _drm_mga_indices {
-       int idx;                /* buffer to queue */
-       unsigned int start;             
-       unsigned int end;               
-       int discard;            /* client finished with buffer?  */
-} drm_mga_indices_t;
+typedef struct _drm_mga_blit {
+       unsigned int planemask;
+       unsigned int srcorg;
+       unsigned int dstorg;
+       int src_pitch, dst_pitch;
+       int delta_sx, delta_sy;
+       int delta_dx, delta_dy;
+       int height, ydir;               /* flip image vertically */
+       int source_pitch, dest_pitch;
+} drm_mga_blit_t;
 
 #endif
index 3937d97174ed560a18c19f7a8aa90e47817eb86f..91216d24f67a3240f77815a1b0e51556ba6797ad 100644 (file)
@@ -1,4 +1,4 @@
-/* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*-
+/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*-
  * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
  *
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * 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
+ * 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>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #include <linux/config.h>
+#include "mga.h"
 #include "drmP.h"
 #include "mga_drv.h"
 
-#define MGA_NAME        "mga"
-#define MGA_DESC        "Matrox G200/G400"
-#define MGA_DATE        "20000928"
-#define MGA_MAJOR       2
-#define MGA_MINOR       0
-#define MGA_PATCHLEVEL  1
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
 
-static drm_device_t          mga_device;
-drm_ctx_t                    mga_res_ctx;
-
-static struct file_operations mga_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#endif
-       open:    mga_open,
-       flush:   drm_flush,
-       release: mga_release,
-       ioctl:   mga_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
+#define DRIVER_NAME            "mga"
+#define DRIVER_DESC            "Matrox G200/G400"
+#define DRIVER_DATE            "20010321"
 
-static struct miscdevice      mga_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  MGA_NAME,
-       fops:  &mga_fops,
-};
+#define DRIVER_MAJOR           3
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      2
 
-static drm_ioctl_desc_t              mga_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]     = { mga_version,    0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]  = { drm_getunique,  0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]   = { drm_getmagic,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]   = { drm_irq_busid,  0, 1 },
+#define DRIVER_IOCTLS                                                     \
+       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]         = { mga_dma_buffers, 1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)]    = { mga_dma_init,    1, 1 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)]   = { mga_dma_reset,   1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)]    = { mga_dma_swap,    1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 }, \
+       [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_dma_blit,    1, 0 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]  = { drm_setunique,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]       = { drm_block,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]     = { drm_unblock,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]     = { mga_control,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]  = { drm_authmagic,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]     = { drm_addmap,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]    = { mga_addbufs,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]   = { mga_markbufs,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]   = { mga_infobufs,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]    = { mga_mapbufs,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]   = { mga_freebufs,   1, 0 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]     = { mga_addctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]      = { mga_rmctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]     = { mga_modctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]     = { mga_getctx,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]  = { mga_switchctx,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]     = { mga_newctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]     = { mga_resctx,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]    = { drm_adddraw,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]     = { drm_rmdraw,     1, 1 },
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
 
-       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]         = { mga_dma,        1, 0 },
 
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]        = { mga_lock,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]      = { mga_unlock,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]      = { drm_finish,     1, 0 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]  = { drm_agp_enable,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]    = { drm_agp_info,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]   = { drm_agp_alloc,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]    = { drm_agp_free,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]    = { drm_agp_bind,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]  = { drm_agp_unbind,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)]    = { mga_dma_init,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)]    = { mga_swap_bufs,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)]   = { mga_clear_bufs,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)]   = { mga_iload,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)]  = { mga_vertex,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)]   = { mga_flush_ioctl, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_indices,     1, 0 },
-};
-
-#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)
-
-#ifdef MODULE
-static char                  *mga = NULL;
-#endif
-
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("Matrox G200/G400");
-MODULE_PARM(mga, "s");
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
 #ifndef MODULE
-/* mga_options is called by the kernel to parse command-line options passed
- * via the boot-loader (e.g., LILO).  It calls the insmod option routine,
- * drm_parse_drm.
+/* DRM(options) is called by the kernel to parse command-line options
+ * passed via the boot-loader (e.g., LILO).  It calls the insmod option
+ * routine, drm_parse_drm.
  */
 
-static int __init mga_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init mga_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("mga=", mga_options);
-#endif
-
-static int mga_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       drm_dma_setup(dev);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int mga_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       if (dev->dev_private) mga_dma_cleanup(dev);
-       if (dev->irq) mga_irq_uninstall(dev);
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-                               /* Clear AGP information */
-       if (dev->agp) {
-               drm_agp_mem_t *entry;
-               drm_agp_mem_t *nexte;
-
-                               /* Remove AGP resources, but leave dev->agp
-                                   intact until cleanup is called. */
-               for (entry = dev->agp->memory; entry; entry = nexte) {
-                       nexte = entry->next;
-                       if (entry->bound) drm_unbind_agp(entry->memory);
-                       drm_free_agp(entry->memory, entry->pages);
-                       drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               }
-               dev->agp->memory = NULL;
-
-               if (dev->agp->acquired) _drm_agp_release();
-
-               dev->agp->acquired = 0;
-               dev->agp->enabled  = 0;
-       }
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
-#endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       if (dev->queuelist) {
-               for (i = 0; i < dev->queue_count; i++) {
-                       drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
-                       if (dev->queuelist[i]) {
-                               drm_free(dev->queuelist[i],
-                                        sizeof(*dev->queuelist[0]),
-                                        DRM_MEM_QUEUES);
-                               dev->queuelist[i] = NULL;
-                       }
-               }
-               drm_free(dev->queuelist,
-                        dev->queue_slots * sizeof(*dev->queuelist),
-                        DRM_MEM_QUEUES);
-               dev->queuelist   = NULL;
-       }
-
-       drm_dma_takedown(dev);
-
-       dev->queue_count     = 0;
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-/* mga_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init mga_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &mga_device;
-
-       DRM_DEBUG("\n");
-
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
-
-#ifdef MODULE
-       drm_parse_options(mga);
+__setup( DRIVER_NAME "=", mga_options );
 #endif
-       if ((retcode = misc_register(&mga_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", MGA_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, mga_misc.minor);
-       dev->name   = MGA_NAME;
 
-       drm_mem_init();
-       drm_proc_init(dev);
-       dev->agp    = drm_agp_init();
-       if(dev->agp == NULL) {
-               DRM_INFO("The mga drm module requires the agpgart module"
-                        " to function correctly\nPlease load the agpgart"
-                        " module before you load the mga module\n");
-               drm_proc_cleanup();
-               misc_deregister(&mga_misc);
-               mga_takedown(dev);
-               return -ENOMEM;
-       }
-#ifdef CONFIG_MTRR
-       dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
-                                     dev->agp->agp_info.aper_size * 1024 * 1024,
-                                     MTRR_TYPE_WRCOMB,
-                                     1);
-#endif
-       if((retcode = drm_ctxbitmap_init(dev))) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               drm_proc_cleanup();
-               misc_deregister(&mga_misc);
-               mga_takedown(dev);
-               return retcode;
-       }
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-                MGA_NAME,
-                MGA_MAJOR,
-                MGA_MINOR,
-                MGA_PATCHLEVEL,
-                MGA_DATE,
-                mga_misc.minor);
 
-       return 0;
-}
-
-/* mga_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit mga_cleanup(void)
-{
-       drm_device_t          *dev = &mga_device;
-
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&mga_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       drm_ctxbitmap_cleanup(dev);
-#ifdef CONFIG_MTRR
-       if(dev->agp && dev->agp->agp_mtrr) {
-               int retval;
-               retval = mtrr_del(dev->agp->agp_mtrr,
-                                 dev->agp->agp_info.aper_base,
-                                 dev->agp->agp_info.aper_size * 1024*1024);
-               DRM_DEBUG("mtrr_del = %d\n", retval);
-       }
-#endif
-
-       mga_takedown(dev);
-       if (dev->agp) {
-               drm_agp_uninit();
-               drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-               dev->agp = NULL;
-       }
-}
-
-module_init(mga_init);
-module_exit(mga_cleanup);
-
-
-int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                \
-       len = strlen(value);                                 \
-       if (len > name##_len) len = name##_len;              \
-       name##_len = strlen(value);                          \
-       if (len && name) {                                   \
-               if (copy_to_user(name, value, len))          \
-                       return -EFAULT;                      \
-       }
-
-       version.version_major      = MGA_MAJOR;
-       version.version_minor      = MGA_MINOR;
-       version.version_patchlevel = MGA_PATCHLEVEL;
-
-       DRM_COPY(version.name, MGA_NAME);
-       DRM_COPY(version.date, MGA_DATE);
-       DRM_COPY(version.desc, MGA_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int mga_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &mga_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return mga_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-       return retcode;
-}
-
-int mga_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev    = priv->dev;
-       DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
-                 current->pid, dev->device, dev->open_count);
-
-       if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
-           && dev->lock.pid == current->pid) {
-               mga_reclaim_buffers(dev, priv->pid);
-               DRM_INFO("Process %d dead (ctx %d, d_s = 0x%02lx)\n",
-                        current->pid,
-                        _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock),
-                        dev->dev_private ?
-                        ((drm_mga_private_t *)dev->dev_private)
-                        ->dispatch_status
-                        : 0);
-
-               if (dev->dev_private)
-                       ((drm_mga_private_t *)dev->dev_private)
-                               ->dispatch_status &= MGA_IN_DISPATCH;
-               
-               drm_lock_free(dev,
-                             &dev->lock.hw_lock->lock,
-                             _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       } else if (dev->lock.hw_lock) {
-               /* The lock is required to reclaim buffers */
-               DECLARE_WAITQUEUE(entry, current);
-               add_wait_queue(&dev->lock.lock_queue, &entry);
-               for (;;) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       if (!dev->lock.hw_lock) {
-                               /* Device has been unregistered */
-                               retcode = -EINTR;
-                               break;
-                       }
-                       if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                         DRM_KERNEL_CONTEXT)) {
-                               dev->lock.pid       = priv->pid;
-                               dev->lock.lock_time = jiffies;
-                               atomic_inc(&dev->total_locks);
-                               break;  /* Got lock */
-                       }
-                               /* Contention */
-                       atomic_inc(&dev->total_sleeps);
-                       schedule();
-                       if (signal_pending(current)) {
-                               retcode = -ERESTARTSYS;
-                               break;
-                       }
-               }
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->lock.lock_queue, &entry);
-               if(!retcode) {
-                       mga_reclaim_buffers(dev, priv->pid);
-                       if (dev->dev_private)
-                               ((drm_mga_private_t *)dev->dev_private)
-                                       ->dispatch_status &= MGA_IN_DISPATCH;
-                       drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                     DRM_KERNEL_CONTEXT);
-               }
-       }
-       drm_fasync(-1, filp, 0);
-
-       down(&dev->struct_sem);
-       if (priv->remove_auth_on_close == 1) {
-               drm_file_t *temp = dev->file_first;
-               while(temp) {
-                       temp->authenticated = 0;
-                       temp = temp->next;
-               }
-       }
-       if (priv->prev) priv->prev->next = priv->next;
-       else            dev->file_first  = priv->next;
-       if (priv->next) priv->next->prev = priv->prev;
-       else            dev->file_last   = priv->prev;
-       up(&dev->struct_sem);
-
-       drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-#if LINUX_VERSION_CODE < 0x020333
-       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-       atomic_inc(&dev->total_close);
-       spin_lock(&dev->count_lock);
-       if (!--dev->open_count) {
-               if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                       DRM_ERROR("Device busy: %d %d\n",
-                                 atomic_read(&dev->ioctl_count),
-                                 dev->blocked);
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return -EBUSY;
-               }
-               spin_unlock(&dev->count_lock);
-               unlock_kernel();
-               return mga_takedown(dev);
-       }
-       spin_unlock(&dev->count_lock);
-       unlock_kernel();
-       return retcode;
-}
-
-
-/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-
-int mga_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       if (nr >= MGA_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &mga_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function: pid = %d, cmd = 0x%02x,"
-                                 " nr = 0x%02x, dev 0x%x, auth = %d\n",
-                                 current->pid, cmd, nr, dev->device,
-                                 priv->authenticated);
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-       mga_dma_schedule(dev, 1);
-
-       if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                         DRM_KERNEL_CONTEXT)) DRM_ERROR("\n");
-
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
index 2419b0493ffcd83622d647f1c019891c13b9b7f0..bb3d21b4c530cfef76ca3cdff2d94f784c5892dc 100644 (file)
@@ -1,4 +1,4 @@
-/* mga_drv.h -- Private header for the Matrox g200/g400 driver -*- linux-c -*-
+/* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*-
  * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
  *
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * 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
+ * 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>
- *         Jeff Hartmann <jhartmann@valinux.com>
+ * 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>
  */
 
-#ifndef _MGA_DRV_H_
-#define _MGA_DRV_H_
+#ifndef __MGA_DRV_H__
+#define __MGA_DRV_H__
 
-#define MGA_BUF_IN_USE         0
-#define MGA_BUF_SWAP_PENDING   1
-#define MGA_BUF_FORCE_FIRE     2
-#define MGA_BUF_NEEDS_OVERFLOW 3
+typedef struct drm_mga_primary_buffer {
+       u8 *start;
+       u8 *end;
+       int size;
 
-typedef struct {
-       long buffer_status; /* long req'd for set_bit() --RR */
-       int num_dwords;
-       int max_dwords;
-       u32 *current_dma_ptr;
-       u32 *head;
-       u32 phys_head;
-       unsigned int prim_age;
-       int sec_used;
-       int idx;
-} drm_mga_prim_buf_t;
-
-typedef struct _drm_mga_freelist {
-       __volatile__ unsigned int age;
+       u32 tail;
+       int space;
+       volatile int wrapped;
+
+       volatile u32 *status;
+
+       u32 last_flush;
+       u32 last_wrap;
+
+       u32 high_mark;
+
+       spinlock_t list_lock;
+} drm_mga_primary_buffer_t;
+
+typedef struct drm_mga_freelist {
+       struct drm_mga_freelist *next;
+       struct drm_mga_freelist *prev;
+       drm_mga_age_t age;
        drm_buf_t *buf;
-       struct _drm_mga_freelist *next;
-       struct _drm_mga_freelist *prev;
 } drm_mga_freelist_t;
 
-#define MGA_IN_DISPATCH   0
-#define MGA_IN_FLUSH      1
-#define MGA_IN_WAIT       2
-#define MGA_IN_GETBUF    3
-
-typedef struct _drm_mga_private {
-       long dispatch_status;  /* long req'd for set_bit() --RR */
-       unsigned int next_prim_age;
-       __volatile__ unsigned int last_prim_age;
-       int reserved_map_idx;
-       int buffer_map_idx;
-       drm_mga_sarea_t *sarea_priv;
-       int primary_size;
-       int warp_ucode_size;
-       int chipset;
-       unsigned int frontOffset;
-       unsigned int backOffset;
-       unsigned int depthOffset;
-       unsigned int textureOffset;
-       unsigned int textureSize;
-       int cpp;
-       unsigned int stride;
-       int sgram;
-       int use_agp;
-       drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
-       unsigned int WarpPipe;
-       unsigned int vertexsize;
-       atomic_t pending_bufs;
-       void *status_page;
-       unsigned long real_status_page;
-       u8 *ioremap;
-       drm_mga_prim_buf_t **prim_bufs;
-       drm_mga_prim_buf_t *next_prim;
-       drm_mga_prim_buf_t *last_prim;
-       drm_mga_prim_buf_t *current_prim;
-       int current_prim_idx;
+typedef struct {
+       drm_mga_freelist_t *list_entry;
+       int discard;
+       int dispatched;
+} drm_mga_buf_priv_t;
+
+typedef struct drm_mga_private {
+       drm_mga_primary_buffer_t prim;
+       drm_mga_sarea_t *sarea_priv;
+
        drm_mga_freelist_t *head;
        drm_mga_freelist_t *tail;
-       wait_queue_head_t flush_queue;  /* Processes waiting until flush    */
-       wait_queue_head_t wait_queue;   /* Processes waiting until interrupt */
-       wait_queue_head_t buf_queue;    /* Processes waiting for a free buf */
-       /* Some validated register values:
-        */
-       u32 mAccess;
-} drm_mga_private_t;
 
-                               /* mga_drv.c */
-extern int  mga_version(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  mga_open(struct inode *inode, struct file *filp);
-extern int  mga_release(struct inode *inode, struct file *filp);
-extern int  mga_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  mga_unlock(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
+       unsigned int warp_pipe;
+       unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
+
+       int chipset;
+       int usec_timeout;
+
+       u32 clear_cmd;
+       u32 maccess;
+
+       unsigned int fb_cpp;
+       unsigned int front_offset;
+       unsigned int front_pitch;
+       unsigned int back_offset;
+       unsigned int back_pitch;
+
+       unsigned int depth_cpp;
+       unsigned int depth_offset;
+       unsigned int depth_pitch;
+
+       unsigned int texture_offset;
+       unsigned int texture_size;
+
+       drm_map_t *sarea;
+       drm_map_t *fb;
+       drm_map_t *mmio;
+       drm_map_t *status;
+       drm_map_t *warp;
+       drm_map_t *primary;
+       drm_map_t *buffers;
+       drm_map_t *agp_textures;
+} drm_mga_private_t;
 
                                /* mga_dma.c */
-extern int  mga_dma_schedule(drm_device_t *dev, int locked);
-extern int  mga_dma(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-extern int  mga_irq_install(drm_device_t *dev, int irq);
-extern int  mga_irq_uninstall(drm_device_t *dev);
-extern int  mga_control(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  mga_lock(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-
-/* mga_dma_init does init and release */
-extern int mga_dma_init(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int mga_dma_cleanup(drm_device_t *dev);
-extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
-extern unsigned int mga_create_sync_tag(drm_device_t *dev);
-extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
-extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
-extern int mga_advance_primary(drm_device_t *dev);
-extern void mga_reclaim_buffers(drm_device_t *dev, pid_t pid);
-
-
-                               /* mga_bufs.c */
-extern int  mga_addbufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  mga_infobufs(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-extern int  mga_markbufs(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-extern int  mga_freebufs(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-extern int  mga_mapbufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  mga_addmap(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
+extern int mga_dma_init( struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg );
+extern int mga_dma_flush( struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long arg );
+extern int mga_dma_reset( struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long arg );
+extern int mga_dma_buffers( struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long arg );
+
+extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
+extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
+extern int mga_do_dma_reset( drm_mga_private_t *dev_priv );
+extern int mga_do_engine_reset( drm_mga_private_t *dev_priv );
+extern int mga_do_cleanup_dma( drm_device_t *dev );
+
+extern void mga_do_dma_flush( drm_mga_private_t *dev_priv );
+extern void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv );
+extern void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv );
+
+extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
+
                                /* mga_state.c */
-extern int  mga_clear_bufs(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
-extern int  mga_swap_bufs(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  mga_iload(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-extern int  mga_vertex(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-extern int  mga_indices(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-                               /* mga_context.c */
-extern int  mga_resctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  mga_addctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  mga_modctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  mga_getctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  mga_switchctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  mga_newctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  mga_rmctx(struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg);
-
-extern int  mga_context_switch(drm_device_t *dev, int old, int new);
-extern int  mga_context_switch_complete(drm_device_t *dev, int new);
+extern int  mga_dma_clear( struct inode *inode, struct file *filp,
+                          unsigned int cmd, unsigned long arg );
+extern int  mga_dma_swap( struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long arg );
+extern int  mga_dma_vertex( struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long arg );
+extern int  mga_dma_indices( struct inode *inode, struct file *filp,
+                            unsigned int cmd, unsigned long arg );
+extern int  mga_dma_iload( struct inode *inode, struct file *filp,
+                          unsigned int cmd, unsigned long arg );
+extern int  mga_dma_blit( struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long arg );
+
+                               /* mga_warp.c */
+extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
+extern int mga_warp_init( drm_mga_private_t *dev_priv );
 
 #define mga_flush_write_combine()      mb()
 
-typedef enum {
-       TT_GENERAL,
-       TT_BLIT,
-       TT_VECTOR,
-       TT_VERTEX
-} transferType_t;
 
-typedef struct {
-       drm_mga_freelist_t *my_freelist;
-       int discard;
-       int dispatched;
-} drm_mga_buf_priv_t;
+#define MGA_BASE( reg )                ((u32)(dev_priv->mmio->handle))
+#define MGA_ADDR( reg )                (MGA_BASE(reg) + reg)
+
+#define MGA_DEREF( reg )       *(volatile u32 *)MGA_ADDR( reg )
+#define MGA_READ( reg )                MGA_DEREF( reg )
+#define MGA_WRITE( reg, val )  do { MGA_DEREF( reg ) = val; } while (0)
+#define MGA_DEREF8( reg )      *(volatile u8 *)MGA_ADDR( reg )
+#define MGA_WRITE8( reg, val )  do { MGA_DEREF8( reg ) = val; } while (0)
 
 #define DWGREG0        0x1c00
 #define DWGREG0_END    0x1dff
@@ -200,321 +160,470 @@ typedef struct {
 #define DWGREG1_END    0x2dff
 
 #define ISREG0(r)      (r >= DWGREG0 && r <= DWGREG0_END)
-#define ADRINDEX0(r)   (u8)((r - DWGREG0) >> 2)
-#define ADRINDEX1(r)   (u8)(((r - DWGREG1) >> 2) | 0x80)
-#define ADRINDEX(r)    (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r))
-
-#define MGA_VERBOSE 0
-#define MGA_NUM_PRIM_BUFS      8
-
-#define PRIMLOCALS     u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
-                       int outcount, num_dwords
-
-#define PRIM_OVERFLOW(dev, dev_priv, length) do {                         \
-       drm_mga_prim_buf_t *tmp_buf =                                      \
-               dev_priv->prim_bufs[dev_priv->current_prim_idx];           \
-       if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) {   \
-               mga_advance_primary(dev);                                  \
-               mga_dma_schedule(dev, 1);                                  \
-               tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
-       } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||   \
-                  tmp_buf->sec_used > MGA_DMA_BUF_NR/2) {                 \
-               set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status);      \
-               mga_advance_primary(dev);                                  \
-               mga_dma_schedule(dev, 1);                                  \
-               tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
-       }                                                                  \
-       if(MGA_VERBOSE)                                                    \
-               DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__);             \
-       dma_ptr = tmp_buf->current_dma_ptr;                                \
-       num_dwords = tmp_buf->num_dwords;                                  \
-       phys_head = tmp_buf->phys_head;                                    \
-       outcount = 0;                                                      \
-} while(0)
-
-#define PRIMGETPTR(dev_priv) do {                                      \
-       drm_mga_prim_buf_t *tmp_buf =                                   \
-               dev_priv->prim_bufs[dev_priv->current_prim_idx];        \
-       if(MGA_VERBOSE)                                                 \
-               DRM_DEBUG("PRIMGETPTR in %s\n", __FUNCTION__);          \
-       dma_ptr = tmp_buf->current_dma_ptr;                             \
-       num_dwords = tmp_buf->num_dwords;                               \
-       phys_head = tmp_buf->phys_head;                                 \
-       outcount = 0;                                                   \
-} while(0)
-
-#define PRIMPTR(prim_buf) do {                                 \
-       if(MGA_VERBOSE)                                         \
-               DRM_DEBUG("PRIMPTR in %s\n", __FUNCTION__);     \
-       dma_ptr = prim_buf->current_dma_ptr;                    \
-       num_dwords = prim_buf->num_dwords;                      \
-       phys_head = prim_buf->phys_head;                        \
-       outcount = 0;                                           \
-} while(0)
-
-#define PRIMFINISH(prim_buf) do {                              \
-       if (MGA_VERBOSE) {                                      \
-               DRM_DEBUG( "PRIMFINISH in %s\n", __FUNCTION__); \
-                if (outcount & 3)                              \
-                      DRM_DEBUG(" --- truncation\n");          \
-        }                                                      \
-       prim_buf->num_dwords = num_dwords;                      \
-       prim_buf->current_dma_ptr = dma_ptr;                    \
-} while(0)
-
-#define PRIMADVANCE(dev_priv)  do {                            \
-drm_mga_prim_buf_t *tmp_buf =                                  \
-       dev_priv->prim_bufs[dev_priv->current_prim_idx];        \
-       if (MGA_VERBOSE) {                                      \
-               DRM_DEBUG("PRIMADVANCE in %s\n", __FUNCTION__); \
-                if (outcount & 3)                              \
-                      DRM_DEBUG(" --- truncation\n");  \
-        }                                                      \
-       tmp_buf->num_dwords = num_dwords;                       \
-       tmp_buf->current_dma_ptr = dma_ptr;                     \
+#define DMAREG0(r)     (u8)((r - DWGREG0) >> 2)
+#define DMAREG1(r)     (u8)(((r - DWGREG1) >> 2) | 0x80)
+#define DMAREG(r)      (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
+
+
+
+/* ================================================================
+ * Helper macross...
+ */
+
+#define MGA_EMIT_STATE( dev_priv, dirty )                              \
+do {                                                                   \
+       if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) {                        \
+               if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) {        \
+                       mga_g400_emit_state( dev_priv );                \
+               } else {                                                \
+                       mga_g200_emit_state( dev_priv );                \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+#define LOCK_TEST_WITH_RETURN( dev )                                   \
+do {                                                                   \
+       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||           \
+            dev->lock.pid != current->pid ) {                          \
+               DRM_ERROR( "%s called without lock held\n",             \
+                          __FUNCTION__ );                              \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+#define WRAP_TEST_WITH_RETURN( dev_priv )                              \
+do {                                                                   \
+       if ( test_bit( 0, &dev_priv->prim.wrapped ) ) {                 \
+               if ( mga_is_idle( dev_priv ) ) {                        \
+                       mga_do_dma_wrap_end( dev_priv );                \
+               } else if ( dev_priv->prim.space <                      \
+                           dev_priv->prim.high_mark ) {                \
+                       if ( MGA_DMA_DEBUG )                            \
+                               DRM_INFO( __FUNCTION__": wrap...\n" );  \
+                       return -EBUSY;                                  \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+#define WRAP_WAIT_WITH_RETURN( dev_priv )                              \
+do {                                                                   \
+       if ( test_bit( 0, &dev_priv->prim.wrapped ) ) {                 \
+               if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {           \
+                       if ( MGA_DMA_DEBUG )                            \
+                               DRM_INFO( __FUNCTION__": wrap...\n" );  \
+                       return -EBUSY;                                  \
+               }                                                       \
+               mga_do_dma_wrap_end( dev_priv );                        \
+       }                                                               \
+} while (0)
+
+
+/* ================================================================
+ * Primary DMA command stream
+ */
+
+#define MGA_VERBOSE    0
+
+#define DMA_LOCALS     unsigned int write; volatile u8 *prim;
+
+#define DMA_BLOCK_SIZE (5 * sizeof(u32))
+
+#define BEGIN_DMA( n )                                                 \
+do {                                                                   \
+       if ( MGA_VERBOSE ) {                                            \
+               DRM_INFO( "BEGIN_DMA( %d ) in %s\n",                    \
+                         (n), __FUNCTION__ );                          \
+               DRM_INFO( "   space=0x%x req=0x%x\n",                   \
+                         dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
+       }                                                               \
+       prim = dev_priv->prim.start;                                    \
+       write = dev_priv->prim.tail;                                    \
+} while (0)
+
+#define BEGIN_DMA_WRAP()                                               \
+do {                                                                   \
+       if ( MGA_VERBOSE ) {                                            \
+               DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ );        \
+               DRM_INFO( "   space=0x%x\n", dev_priv->prim.space );    \
+       }                                                               \
+       prim = dev_priv->prim.start;                                    \
+       write = dev_priv->prim.tail;                                    \
+} while (0)
+
+#define ADVANCE_DMA()                                                  \
+do {                                                                   \
+       dev_priv->prim.tail = write;                                    \
+       if ( MGA_VERBOSE ) {                                            \
+               DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n",        \
+                         write, dev_priv->prim.space );                \
+       }                                                               \
 } while (0)
 
-#define PRIMUPDATE(dev_priv)   do {                                    \
-       drm_mga_prim_buf_t *tmp_buf =                                   \
-               dev_priv->prim_bufs[dev_priv->current_prim_idx];        \
-       tmp_buf->sec_used++;                                            \
+#define FLUSH_DMA()                                                    \
+do {                                                                   \
+       if ( 0 ) {                                                      \
+               DRM_INFO( __FUNCTION__ ":\n" );                         \
+               DRM_INFO( "   tail=0x%06x head=0x%06lx\n",              \
+                         dev_priv->prim.tail,                          \
+                         MGA_READ( MGA_PRIMADDRESS ) -                 \
+                         dev_priv->primary->offset );                  \
+       }                                                               \
+       if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) {                \
+               if ( dev_priv->prim.space <                             \
+                    dev_priv->prim.high_mark ) {                       \
+                       mga_do_dma_wrap_start( dev_priv );              \
+               } else {                                                \
+                       mga_do_dma_flush( dev_priv );                   \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+/* Never use this, always use DMA_BLOCK(...) for primary DMA output.
+ */
+#define DMA_WRITE( offset, val )                                       \
+do {                                                                   \
+       if ( MGA_VERBOSE ) {                                            \
+               DRM_INFO( "   DMA_WRITE( 0x%08x ) at 0x%04x\n",         \
+                         (u32)(val), write + (offset) * sizeof(u32) ); \
+       }                                                               \
+       *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \
 } while (0)
 
-#define AGEBUF(dev_priv, buf_priv)     do {                            \
-       drm_mga_prim_buf_t *tmp_buf =                                   \
-               dev_priv->prim_bufs[dev_priv->current_prim_idx];        \
-       buf_priv->my_freelist->age = tmp_buf->prim_age;                 \
+#define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 )    \
+do {                                                                   \
+       DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) |                          \
+                      (DMAREG( reg1 ) << 8) |                          \
+                      (DMAREG( reg2 ) << 16) |                         \
+                      (DMAREG( reg3 ) << 24)) );                       \
+       DMA_WRITE( 1, val0 );                                           \
+       DMA_WRITE( 2, val1 );                                           \
+       DMA_WRITE( 3, val2 );                                           \
+       DMA_WRITE( 4, val3 );                                           \
+       write += DMA_BLOCK_SIZE;                                        \
 } while (0)
 
 
-#define PRIMOUTREG(reg, val) do {                                      \
-       tempIndex[outcount]=ADRINDEX(reg);                              \
-       dma_ptr[1+outcount] = val;                                      \
-       if (MGA_VERBOSE)                                                \
-               DRM_DEBUG("   PRIMOUT %d: 0x%x -- 0x%x\n",              \
-                      num_dwords + 1 + outcount, ADRINDEX(reg), val);  \
-       if( ++outcount == 4) {                                          \
-               outcount = 0;                                           \
-               dma_ptr[0] = *(unsigned long *)tempIndex;               \
-               dma_ptr+=5;                                             \
-               num_dwords += 5;                                        \
+/* Buffer aging via primary DMA stream head pointer.
+ */
+
+#define SET_AGE( age, h, w )                                           \
+do {                                                                   \
+       (age)->head = h;                                                \
+       (age)->wrap = w;                                                \
+} while (0)
+
+#define TEST_AGE( age, h, w )          ( (age)->wrap < w ||            \
+                                         ( (age)->wrap == w &&         \
+                                           (age)->head < h ) )
+
+#define AGE_BUFFER( buf_priv )                                         \
+do {                                                                   \
+       drm_mga_freelist_t *entry = (buf_priv)->list_entry;             \
+       if ( (buf_priv)->dispatched ) {                                 \
+               entry->age.head = (dev_priv->prim.tail +                \
+                                  dev_priv->primary->offset);          \
+               entry->age.wrap = dev_priv->sarea_priv->last_wrap;      \
+       } else {                                                        \
+               entry->age.head = 0;                                    \
+               entry->age.wrap = 0;                                    \
        }                                                               \
-}while (0)
+} while (0)
+
+
+#define MGA_ENGINE_IDLE_MASK           (MGA_SOFTRAPEN |                \
+                                        MGA_DWGENGSTS |                \
+                                        MGA_ENDPRDMASTS)
+#define MGA_DMA_IDLE_MASK              (MGA_SOFTRAPEN |                \
+                                        MGA_ENDPRDMASTS)
+
+#define MGA_DMA_DEBUG                  0
+
+
 
 /* A reduced set of the mga registers.
  */
+#define MGA_CRTC_INDEX                 0x1fd4
+
+#define MGA_ALPHACTRL                  0x2c7c
+#define MGA_AR0                        0x1c60
+#define MGA_AR1                        0x1c64
+#define MGA_AR2                        0x1c68
+#define MGA_AR3                        0x1c6c
+#define MGA_AR4                        0x1c70
+#define MGA_AR5                        0x1c74
+#define MGA_AR6                        0x1c78
+
+#define MGA_CXBNDRY                    0x1c80
+#define MGA_CXLEFT                     0x1ca0
+#define MGA_CXRIGHT                    0x1ca4
+
+#define MGA_DMAPAD                     0x1c54
+#define MGA_DSTORG                     0x2cb8
+#define MGA_DWGCTL                     0x1c00
+#      define MGA_OPCOD_MASK                   (15 << 0)
+#      define MGA_OPCOD_TRAP                   (4 << 0)
+#      define MGA_OPCOD_TEXTURE_TRAP           (6 << 0)
+#      define MGA_OPCOD_BITBLT                 (8 << 0)
+#      define MGA_OPCOD_ILOAD                  (9 << 0)
+#      define MGA_ATYPE_MASK                   (7 << 4)
+#      define MGA_ATYPE_RPL                    (0 << 4)
+#      define MGA_ATYPE_RSTR                   (1 << 4)
+#      define MGA_ATYPE_ZI                     (3 << 4)
+#      define MGA_ATYPE_BLK                    (4 << 4)
+#      define MGA_ATYPE_I                      (7 << 4)
+#      define MGA_LINEAR                       (1 << 7)
+#      define MGA_ZMODE_MASK                   (7 << 8)
+#      define MGA_ZMODE_NOZCMP                 (0 << 8)
+#      define MGA_ZMODE_ZE                     (2 << 8)
+#      define MGA_ZMODE_ZNE                    (3 << 8)
+#      define MGA_ZMODE_ZLT                    (4 << 8)
+#      define MGA_ZMODE_ZLTE                   (5 << 8)
+#      define MGA_ZMODE_ZGT                    (6 << 8)
+#      define MGA_ZMODE_ZGTE                   (7 << 8)
+#      define MGA_SOLID                        (1 << 11)
+#      define MGA_ARZERO                       (1 << 12)
+#      define MGA_SGNZERO                      (1 << 13)
+#      define MGA_SHIFTZERO                    (1 << 14)
+#      define MGA_BOP_MASK                     (15 << 16)
+#      define MGA_BOP_ZERO                     (0 << 16)
+#      define MGA_BOP_DST                      (10 << 16)
+#      define MGA_BOP_SRC                      (12 << 16)
+#      define MGA_BOP_ONE                      (15 << 16)
+#      define MGA_TRANS_SHIFT                  20
+#      define MGA_TRANS_MASK                   (15 << 20)
+#      define MGA_BLTMOD_MASK                  (15 << 25)
+#      define MGA_BLTMOD_BMONOLEF              (0 << 25)
+#      define MGA_BLTMOD_BMONOWF               (4 << 25)
+#      define MGA_BLTMOD_PLAN                  (1 << 25)
+#      define MGA_BLTMOD_BFCOL                 (2 << 25)
+#      define MGA_BLTMOD_BU32BGR               (3 << 25)
+#      define MGA_BLTMOD_BU32RGB               (7 << 25)
+#      define MGA_BLTMOD_BU24BGR               (11 << 25)
+#      define MGA_BLTMOD_BU24RGB               (15 << 25)
+#      define MGA_PATTERN                      (1 << 29)
+#      define MGA_TRANSC                       (1 << 30)
+#      define MGA_CLIPDIS                      (1 << 31)
+#define MGA_DWGSYNC                    0x2c4c
+
+#define MGA_FCOL                       0x1c24
+#define MGA_FIFOSTATUS                         0x1e10
+#define MGA_FOGCOL                     0x1cf4
+#define MGA_FXBNDRY                    0x1c84
+#define MGA_FXLEFT                     0x1ca8
+#define MGA_FXRIGHT                    0x1cac
+
+#define MGA_ICLEAR                     0x1e18
+#      define MGA_SOFTRAPICLR                  (1 << 0)
+#define MGA_IEN                        0x1e1c
+#      define MGA_SOFTRAPIEN                   (1 << 0)
+
+#define MGA_LEN                        0x1c5c
+
+#define MGA_MACCESS                    0x1c04
+
+#define MGA_PITCH                      0x1c8c
+#define MGA_PLNWT                      0x1c1c
+#define MGA_PRIMADDRESS                0x1e58
+#      define MGA_DMA_GENERAL                  (0 << 0)
+#      define MGA_DMA_BLIT                     (1 << 0)
+#      define MGA_DMA_VECTOR                   (2 << 0)
+#      define MGA_DMA_VERTEX                   (3 << 0)
+#define MGA_PRIMEND                    0x1e5c
+#      define MGA_PRIMNOSTART                  (1 << 0)
+#      define MGA_PAGPXFER                     (1 << 1)
+#define MGA_PRIMPTR                    0x1e50
+#      define MGA_PRIMPTREN0                   (1 << 0)
+#      define MGA_PRIMPTREN1                   (1 << 1)
+
+#define MGA_RST                        0x1e40
+#      define MGA_SOFTRESET                    (1 << 0)
+#      define MGA_SOFTEXTRST                   (1 << 1)
+
+#define MGA_SECADDRESS                         0x2c40
+#define MGA_SECEND                     0x2c44
+#define MGA_SETUPADDRESS               0x2cd0
+#define MGA_SETUPEND                   0x2cd4
+#define MGA_SGN                                0x1c58
+#define MGA_SOFTRAP                    0x2c48
+#define MGA_SRCORG                     0x2cb4
+#      define MGA_SRMMAP_MASK                  (1 << 0)
+#      define MGA_SRCMAP_FB                    (0 << 0)
+#      define MGA_SRCMAP_SYSMEM                (1 << 0)
+#      define MGA_SRCACC_MASK                  (1 << 1)
+#      define MGA_SRCACC_PCI                   (0 << 1)
+#      define MGA_SRCACC_AGP                   (1 << 1)
+#define MGA_STATUS                     0x1e14
+#      define MGA_SOFTRAPEN                    (1 << 0)
+#      define MGA_DWGENGSTS                    (1 << 16)
+#      define MGA_ENDPRDMASTS                  (1 << 17)
+#define MGA_STENCIL                    0x2cc8
+#define MGA_STENCILCTL                         0x2ccc
+
+#define MGA_TDUALSTAGE0                0x2cf8
+#define MGA_TDUALSTAGE1                0x2cfc
+#define MGA_TEXBORDERCOL               0x2c5c
+#define MGA_TEXCTL                     0x2c30
+#define MGA_TEXCTL2                    0x2c3c
+#      define MGA_DUALTEX                      (1 << 7)
+#      define MGA_G400_TC2_MAGIC               (1 << 15)
+#      define MGA_MAP1_ENABLE                  (1 << 31)
+#define MGA_TEXFILTER                  0x2c58
+#define MGA_TEXHEIGHT                  0x2c2c
+#define MGA_TEXORG                     0x2c24
+#      define MGA_TEXORGMAP_MASK               (1 << 0)
+#      define MGA_TEXORGMAP_FB                 (0 << 0)
+#      define MGA_TEXORGMAP_SYSMEM             (1 << 0)
+#      define MGA_TEXORGACC_MASK               (1 << 1)
+#      define MGA_TEXORGACC_PCI                (0 << 1)
+#      define MGA_TEXORGACC_AGP                (1 << 1)
+#define MGA_TEXORG1                    0x2ca4
+#define MGA_TEXORG2                    0x2ca8
+#define MGA_TEXORG3                    0x2cac
+#define MGA_TEXORG4                    0x2cb0
+#define MGA_TEXTRANS                   0x2c34
+#define MGA_TEXTRANSHIGH               0x2c38
+#define MGA_TEXWIDTH                   0x2c28
+
+#define MGA_WACCEPTSEQ                         0x1dd4
+#define MGA_WCODEADDR                  0x1e6c
+#define MGA_WFLAG                      0x1dc4
+#define MGA_WFLAG1                     0x1de0
+#define MGA_WFLAGNB                    0x1e64
+#define MGA_WFLAGNB1                   0x1e08
+#define MGA_WGETMSB                    0x1dc8
+#define MGA_WIADDR                     0x1dc0
+#define MGA_WIADDR2                    0x1dd8
+#      define MGA_WMODE_SUSPEND                (0 << 0)
+#      define MGA_WMODE_RESUME                 (1 << 0)
+#      define MGA_WMODE_JUMP                   (2 << 0)
+#      define MGA_WMODE_START                  (3 << 0)
+#      define MGA_WAGP_ENABLE                  (1 << 2)
+#define MGA_WMISC                      0x1e70
+#      define MGA_WUCODECACHE_ENABLE           (1 << 0)
+#      define MGA_WMASTER_ENABLE               (1 << 1)
+#      define MGA_WCACHEFLUSH_ENABLE           (1 << 3)
+#define MGA_WVRTXSZ                    0x1dcc
+
+#define MGA_YBOT                       0x1c9c
+#define MGA_YDST                       0x1c90
+#define MGA_YDSTLEN                    0x1c88
+#define MGA_YDSTORG                    0x1c94
+#define MGA_YTOP                       0x1c98
+
+#define MGA_ZORG                       0x1c0c
+
+/* This finishes the current batch of commands
+ */
+#define MGA_EXEC                       0x0100
 
-#define MGAREG_MGA_EXEC                        0x0100
-#define MGAREG_ALPHACTRL                       0x2c7c
-#define MGAREG_AR0                             0x1c60
-#define MGAREG_AR1                             0x1c64
-#define MGAREG_AR2                             0x1c68
-#define MGAREG_AR3                             0x1c6c
-#define MGAREG_AR4                             0x1c70
-#define MGAREG_AR5                             0x1c74
-#define MGAREG_AR6                             0x1c78
-#define MGAREG_CXBNDRY                         0x1c80
-#define MGAREG_CXLEFT                          0x1ca0
-#define MGAREG_CXRIGHT                         0x1ca4
-#define MGAREG_DMAPAD                          0x1c54
-#define MGAREG_DSTORG                          0x2cb8
-#define MGAREG_DWGCTL                          0x1c00
-#define MGAREG_DWGSYNC                         0x2c4c
-#define MGAREG_FCOL                            0x1c24
-#define MGAREG_FIFOSTATUS                      0x1e10
-#define MGAREG_FOGCOL                          0x1cf4
-#define MGAREG_FXBNDRY                         0x1c84
-#define MGAREG_FXLEFT                          0x1ca8
-#define MGAREG_FXRIGHT                         0x1cac
-#define MGAREG_ICLEAR                          0x1e18
-#define MGAREG_IEN                             0x1e1c
-#define MGAREG_LEN                             0x1c5c
-#define MGAREG_MACCESS                         0x1c04
-#define MGAREG_PITCH                           0x1c8c
-#define MGAREG_PLNWT                           0x1c1c
-#define MGAREG_PRIMADDRESS                     0x1e58
-#define MGAREG_PRIMEND                         0x1e5c
-#define MGAREG_PRIMPTR                         0x1e50
-#define MGAREG_SECADDRESS                      0x2c40
-#define MGAREG_SECEND                          0x2c44
-#define MGAREG_SETUPADDRESS                    0x2cd0
-#define MGAREG_SETUPEND                        0x2cd4
-#define MGAREG_SOFTRAP                         0x2c48
-#define MGAREG_SRCORG                          0x2cb4
-#define MGAREG_STATUS                          0x1e14
-#define MGAREG_STENCIL                         0x2cc8
-#define MGAREG_STENCILCTL                      0x2ccc
-#define MGAREG_TDUALSTAGE0                     0x2cf8
-#define MGAREG_TDUALSTAGE1                     0x2cfc
-#define MGAREG_TEXBORDERCOL                    0x2c5c
-#define MGAREG_TEXCTL                          0x2c30
-#define MGAREG_TEXCTL2                         0x2c3c
-#define MGAREG_TEXFILTER                       0x2c58
-#define MGAREG_TEXHEIGHT                       0x2c2c
-#define MGAREG_TEXORG                          0x2c24
-#define MGAREG_TEXORG1                         0x2ca4
-#define MGAREG_TEXORG2                         0x2ca8
-#define MGAREG_TEXORG3                         0x2cac
-#define MGAREG_TEXORG4                         0x2cb0
-#define MGAREG_TEXTRANS                        0x2c34
-#define MGAREG_TEXTRANSHIGH                    0x2c38
-#define MGAREG_TEXWIDTH                        0x2c28
-#define MGAREG_WACCEPTSEQ                      0x1dd4
-#define MGAREG_WCODEADDR                       0x1e6c
-#define MGAREG_WFLAG                           0x1dc4
-#define MGAREG_WFLAG1                          0x1de0
-#define MGAREG_WFLAGNB                         0x1e64
-#define MGAREG_WFLAGNB1                        0x1e08
-#define MGAREG_WGETMSB                         0x1dc8
-#define MGAREG_WIADDR                          0x1dc0
-#define MGAREG_WIADDR2                         0x1dd8
-#define MGAREG_WMISC                           0x1e70
-#define MGAREG_WVRTXSZ                         0x1dcc
-#define MGAREG_YBOT                            0x1c9c
-#define MGAREG_YDST                            0x1c90
-#define MGAREG_YDSTLEN                         0x1c88
-#define MGAREG_YDSTORG                         0x1c94
-#define MGAREG_YTOP                            0x1c98
-#define MGAREG_ZORG                            0x1c0c
-
-/* Warp registers */
-#define MGAREG_WR0                              0x2d00
-#define MGAREG_WR1                              0x2d04
-#define MGAREG_WR2                              0x2d08
-#define MGAREG_WR3                              0x2d0c
-#define MGAREG_WR4                              0x2d10
-#define MGAREG_WR5                              0x2d14
-#define MGAREG_WR6                              0x2d18
-#define MGAREG_WR7                              0x2d1c
-#define MGAREG_WR8                              0x2d20
-#define MGAREG_WR9                              0x2d24
-#define MGAREG_WR10                             0x2d28
-#define MGAREG_WR11                             0x2d2c
-#define MGAREG_WR12                             0x2d30
-#define MGAREG_WR13                             0x2d34
-#define MGAREG_WR14                             0x2d38
-#define MGAREG_WR15                             0x2d3c
-#define MGAREG_WR16                             0x2d40
-#define MGAREG_WR17                             0x2d44
-#define MGAREG_WR18                             0x2d48
-#define MGAREG_WR19                             0x2d4c
-#define MGAREG_WR20                             0x2d50
-#define MGAREG_WR21                             0x2d54
-#define MGAREG_WR22                             0x2d58
-#define MGAREG_WR23                             0x2d5c
-#define MGAREG_WR24                             0x2d60
-#define MGAREG_WR25                             0x2d64
-#define MGAREG_WR26                             0x2d68
-#define MGAREG_WR27                             0x2d6c
-#define MGAREG_WR28                             0x2d70
-#define MGAREG_WR29                             0x2d74
-#define MGAREG_WR30                             0x2d78
-#define MGAREG_WR31                             0x2d7c
-#define MGAREG_WR32                             0x2d80
-#define MGAREG_WR33                             0x2d84
-#define MGAREG_WR34                             0x2d88
-#define MGAREG_WR35                             0x2d8c
-#define MGAREG_WR36                             0x2d90
-#define MGAREG_WR37                             0x2d94
-#define MGAREG_WR38                             0x2d98
-#define MGAREG_WR39                             0x2d9c
-#define MGAREG_WR40                             0x2da0
-#define MGAREG_WR41                             0x2da4
-#define MGAREG_WR42                             0x2da8
-#define MGAREG_WR43                             0x2dac
-#define MGAREG_WR44                             0x2db0
-#define MGAREG_WR45                             0x2db4
-#define MGAREG_WR46                             0x2db8
-#define MGAREG_WR47                             0x2dbc
-#define MGAREG_WR48                             0x2dc0
-#define MGAREG_WR49                             0x2dc4
-#define MGAREG_WR50                             0x2dc8
-#define MGAREG_WR51                             0x2dcc
-#define MGAREG_WR52                             0x2dd0
-#define MGAREG_WR53                             0x2dd4
-#define MGAREG_WR54                             0x2dd8
-#define MGAREG_WR55                             0x2ddc
-#define MGAREG_WR56                             0x2de0
-#define MGAREG_WR57                             0x2de4
-#define MGAREG_WR58                             0x2de8
-#define MGAREG_WR59                             0x2dec
-#define MGAREG_WR60                             0x2df0
-#define MGAREG_WR61                             0x2df4
-#define MGAREG_WR62                             0x2df8
-#define MGAREG_WR63                             0x2dfc
-
-#define PDEA_pagpxfer_enable                   0x2
-
-#define WIA_wmode_suspend                      0x0
-#define WIA_wmode_start                        0x3
-#define WIA_wagp_agp                           0x4
-
-#define DC_opcod_line_open                     0x0
-#define DC_opcod_autoline_open                         0x1
-#define DC_opcod_line_close                    0x2
-#define DC_opcod_autoline_close                0x3
-#define DC_opcod_trap                          0x4
-#define DC_opcod_texture_trap                  0x6
-#define DC_opcod_bitblt                        0x8
-#define DC_opcod_iload                                 0x9
-#define DC_atype_rpl                           0x0
-#define DC_atype_rstr                          0x10
-#define DC_atype_zi                            0x30
-#define DC_atype_blk                           0x40
-#define DC_atype_i                             0x70
-#define DC_linear_xy                           0x0
-#define DC_linear_linear                       0x80
-#define DC_zmode_nozcmp                        0x0
-#define DC_zmode_ze                            0x200
-#define DC_zmode_zne                           0x300
-#define DC_zmode_zlt                           0x400
-#define DC_zmode_zlte                          0x500
-#define DC_zmode_zgt                           0x600
-#define DC_zmode_zgte                          0x700
-#define DC_solid_disable                       0x0
-#define DC_solid_enable                        0x800
-#define DC_arzero_disable                      0x0
-#define DC_arzero_enable                       0x1000
-#define DC_sgnzero_disable                     0x0
-#define DC_sgnzero_enable                      0x2000
-#define DC_shftzero_disable                    0x0
-#define DC_shftzero_enable                     0x4000
-#define DC_bop_SHIFT                           16
-#define DC_trans_SHIFT                                 20
-#define DC_bltmod_bmonolef                     0x0
-#define DC_bltmod_bmonowf                      0x8000000
-#define DC_bltmod_bplan                        0x2000000
-#define DC_bltmod_bfcol                        0x4000000
-#define DC_bltmod_bu32bgr                      0x6000000
-#define DC_bltmod_bu32rgb                      0xe000000
-#define DC_bltmod_bu24bgr                      0x16000000
-#define DC_bltmod_bu24rgb                      0x1e000000
-#define DC_pattern_disable                     0x0
-#define DC_pattern_enable                      0x20000000
-#define DC_transc_disable                      0x0
-#define DC_transc_enable                       0x40000000
-#define DC_clipdis_disable                     0x0
-#define DC_clipdis_enable                      0x80000000
-
-
-#define SETADD_mode_vertlist                           0x0
-
-
-#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable |              \
-                      DC_sgnzero_enable | DC_shftzero_enable |         \
-                      (0xC << DC_bop_SHIFT) | DC_clipdis_enable |      \
-                      DC_solid_enable | DC_transc_enable)
-
-
-#define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy |  \
-                     DC_solid_disable | DC_arzero_disable |            \
-                     DC_sgnzero_enable | DC_shftzero_enable |          \
-                     (0xC << DC_bop_SHIFT) | DC_bltmod_bfcol |         \
-                     DC_pattern_disable | DC_transc_disable |          \
-                     DC_clipdis_enable)                                \
-
-#define MGA_FLUSH_CMD (DC_opcod_texture_trap | (0xF << DC_trans_SHIFT) |\
-                      DC_arzero_enable | DC_sgnzero_enable |           \
-                      DC_atype_i)
+/* Warp registers
+ */
+#define MGA_WR0                                0x2d00
+#define MGA_WR1                                0x2d04
+#define MGA_WR2                                0x2d08
+#define MGA_WR3                                0x2d0c
+#define MGA_WR4                                0x2d10
+#define MGA_WR5                                0x2d14
+#define MGA_WR6                                0x2d18
+#define MGA_WR7                                0x2d1c
+#define MGA_WR8                                0x2d20
+#define MGA_WR9                                0x2d24
+#define MGA_WR10                       0x2d28
+#define MGA_WR11                       0x2d2c
+#define MGA_WR12                       0x2d30
+#define MGA_WR13                       0x2d34
+#define MGA_WR14                       0x2d38
+#define MGA_WR15                       0x2d3c
+#define MGA_WR16                       0x2d40
+#define MGA_WR17                       0x2d44
+#define MGA_WR18                       0x2d48
+#define MGA_WR19                       0x2d4c
+#define MGA_WR20                       0x2d50
+#define MGA_WR21                       0x2d54
+#define MGA_WR22                       0x2d58
+#define MGA_WR23                       0x2d5c
+#define MGA_WR24                       0x2d60
+#define MGA_WR25                       0x2d64
+#define MGA_WR26                       0x2d68
+#define MGA_WR27                       0x2d6c
+#define MGA_WR28                       0x2d70
+#define MGA_WR29                       0x2d74
+#define MGA_WR30                       0x2d78
+#define MGA_WR31                       0x2d7c
+#define MGA_WR32                       0x2d80
+#define MGA_WR33                       0x2d84
+#define MGA_WR34                       0x2d88
+#define MGA_WR35                       0x2d8c
+#define MGA_WR36                       0x2d90
+#define MGA_WR37                       0x2d94
+#define MGA_WR38                       0x2d98
+#define MGA_WR39                       0x2d9c
+#define MGA_WR40                       0x2da0
+#define MGA_WR41                       0x2da4
+#define MGA_WR42                       0x2da8
+#define MGA_WR43                       0x2dac
+#define MGA_WR44                       0x2db0
+#define MGA_WR45                       0x2db4
+#define MGA_WR46                       0x2db8
+#define MGA_WR47                       0x2dbc
+#define MGA_WR48                       0x2dc0
+#define MGA_WR49                       0x2dc4
+#define MGA_WR50                       0x2dc8
+#define MGA_WR51                       0x2dcc
+#define MGA_WR52                       0x2dd0
+#define MGA_WR53                       0x2dd4
+#define MGA_WR54                       0x2dd8
+#define MGA_WR55                       0x2ddc
+#define MGA_WR56                       0x2de0
+#define MGA_WR57                       0x2de4
+#define MGA_WR58                       0x2de8
+#define MGA_WR59                       0x2dec
+#define MGA_WR60                       0x2df0
+#define MGA_WR61                       0x2df4
+#define MGA_WR62                       0x2df8
+#define MGA_WR63                       0x2dfc
+#      define MGA_G400_WR_MAGIC                (1 << 6)
+#      define MGA_G400_WR56_MAGIC              0x46480000      /* 12800.0f */
+
+
+#define MGA_ILOAD_ALIGN                64
+#define MGA_ILOAD_MASK         (MGA_ILOAD_ALIGN - 1)
+
+#define MGA_DWGCTL_FLUSH       (MGA_OPCOD_TEXTURE_TRAP |               \
+                                MGA_ATYPE_I |                          \
+                                MGA_ZMODE_NOZCMP |                     \
+                                MGA_ARZERO |                           \
+                                MGA_SGNZERO |                          \
+                                MGA_BOP_SRC |                          \
+                                (15 << MGA_TRANS_SHIFT))
+
+#define MGA_DWGCTL_CLEAR       (MGA_OPCOD_TRAP |                       \
+                                MGA_ZMODE_NOZCMP |                     \
+                                MGA_SOLID |                            \
+                                MGA_ARZERO |                           \
+                                MGA_SGNZERO |                          \
+                                MGA_SHIFTZERO |                        \
+                                MGA_BOP_SRC |                          \
+                                (0 << MGA_TRANS_SHIFT) |               \
+                                MGA_BLTMOD_BMONOLEF |                  \
+                                MGA_TRANSC |                           \
+                                MGA_CLIPDIS)
+
+#define MGA_DWGCTL_COPY                (MGA_OPCOD_BITBLT |                     \
+                                MGA_ATYPE_RPL |                        \
+                                MGA_SGNZERO |                          \
+                                MGA_SHIFTZERO |                        \
+                                MGA_BOP_SRC |                          \
+                                (0 << MGA_TRANS_SHIFT) |               \
+                                MGA_BLTMOD_BFCOL |                     \
+                                MGA_CLIPDIS)
+
+/* Simple idle test.
+ */
+static inline int mga_is_idle( drm_mga_private_t *dev_priv )
+{
+       u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+       return ( status == MGA_ENDPRDMASTS );
+}
 
 #endif
index 15fa3cd70d889206028c1b0d291be717d5cea986..41b2e9a17689c954ad0cf2c12159ecf6c36bfce4 100644 (file)
@@ -1,4 +1,4 @@
-/* mga_state.c -- State support for mga g200/g400 -*- linux-c -*-
+/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*-
  * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com
  *
  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * 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
+ * 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.
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Jeff Hartmann <jhartmann@valinux.com>
- *         Keith Whitwell <keithw@valinux.com>
+ * Authors:
+ *    Jeff Hartmann <jhartmann@valinux.com>
+ *    Keith Whitwell <keithw@valinux.com>
  *
+ * Rewritten by:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "mga.h"
 #include "drmP.h"
 #include "mga_drv.h"
 #include "drm.h"
 
-/* If you change the functions to set state, PLEASE
- * change these values
- */
-
-#define MGAEMITCLIP_SIZE       10
-#define MGAEMITCTX_SIZE                20
-#define MGAG200EMITTEX_SIZE    20
-#define MGAG400EMITTEX0_SIZE   30
-#define MGAG400EMITTEX1_SIZE   25
-#define MGAG400EMITPIPE_SIZE   50
-#define MGAG200EMITPIPE_SIZE   15
 
-#define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
-                       MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \
-                       MGAG400EMITTEX1_SIZE + MGAG400EMITPIPE_SIZE)
+/* ================================================================
+ * DMA hardware state programming functions
+ */
 
-static void mgaEmitClipRect(drm_mga_private_t * dev_priv,
-                           drm_clip_rect_t * box)
+static void mga_emit_clip_rect( drm_mga_private_t *dev_priv,
+                               drm_clip_rect_t *box )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-       PRIMLOCALS;
-
-       /* This takes 10 dwords */
-       PRIMGETPTR(dev_priv);
-
-       /* Force reset of dwgctl on G400 (eliminates clip disable bit) */
-       if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
-#if 0
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DWGSYNC, 0);
-               PRIMOUTREG(MGAREG_DWGSYNC, 0);
-               PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-#else
-               PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
-               PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
-#endif
-       }
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1));
-       PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp);
-       PRIMOUTREG(MGAREG_YBOT, box->y2 * dev_priv->stride / dev_priv->cpp);
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       unsigned int pitch = dev_priv->front_pitch;
+       DMA_LOCALS;
 
-       PRIMADVANCE(dev_priv);
-}
+       BEGIN_DMA( 2 );
 
-static void mgaEmitContext(drm_mga_private_t * dev_priv)
-{
-       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-       PRIMLOCALS;
-
-       /* This takes a max of 20 dwords */
-       PRIMGETPTR(dev_priv);
-
-       PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]);
-       PRIMOUTREG(MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS]);
-       PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]);
-       PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-
-       PRIMOUTREG(MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL]);
-       PRIMOUTREG(MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR]);
-       PRIMOUTREG(MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG]);
-       PRIMOUTREG(MGAREG_ZORG, dev_priv->depthOffset); /* invarient */
-
-       if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
-               PRIMOUTREG(MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG]);
-               PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]);
-               PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]);
-               PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
-
-               PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]);
-               PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-       } else {
-               PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
+       /* Force reset of DWGCTL on G400 (eliminates clip disable bit).
+        */
+       if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) {
+               DMA_BLOCK( MGA_DWGCTL,          ctx->dwgctl,
+                          MGA_LEN + MGA_EXEC,  0x80000000,
+                          MGA_DWGCTL,          ctx->dwgctl,
+                          MGA_LEN + MGA_EXEC,  0x80000000 );
        }
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_CXBNDRY, (box->x2 << 16) | box->x1,
+                  MGA_YTOP,    box->y1 * pitch,
+                  MGA_YBOT,    box->y2 * pitch );
 
-       PRIMADVANCE(dev_priv);
+       ADVANCE_DMA();
 }
 
-static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
+static inline void mga_g200_emit_context( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->TexState[0];
-       PRIMLOCALS;
-
-       PRIMGETPTR(dev_priv);
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       DMA_LOCALS;
 
-       /* This takes 20 dwords */
+       BEGIN_DMA( 3 );
 
-       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2]);
-       PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
-       PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
-       PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
+       DMA_BLOCK( MGA_DSTORG,          ctx->dstorg,
+                  MGA_MACCESS,         ctx->maccess,
+                  MGA_PLNWT,           ctx->plnwt,
+                  MGA_DWGCTL,          ctx->dwgctl );
 
-       PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]);
-       PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]);
-       PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]);
-       PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]);
+       DMA_BLOCK( MGA_ALPHACTRL,       ctx->alphactrl,
+                  MGA_FOGCOL,          ctx->fogcolor,
+                  MGA_WFLAG,           ctx->wflag,
+                  MGA_ZORG,            dev_priv->depth_offset );
 
-       PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
-       PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
-       PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-       PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]);
+       DMA_BLOCK( MGA_FCOL,            ctx->fcol,
+                  MGA_DMAPAD,          0x00000000,
+                  MGA_DMAPAD,          0x00000000,
+                  MGA_DMAPAD,          0x00000000 );
 
-       PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]);
-       PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
-       PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-       PRIMADVANCE(dev_priv);
+       ADVANCE_DMA();
 }
 
-#define TMC_dualtex_enable             0x80
-
-static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
+static inline void mga_g400_emit_context( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->TexState[0];
-       PRIMLOCALS;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       DMA_LOCALS;
 
-       PRIMGETPTR(dev_priv);
+       BEGIN_DMA( 4 );
 
-       /* This takes 30 dwords */
+       DMA_BLOCK( MGA_DSTORG,          ctx->dstorg,
+                  MGA_MACCESS,         ctx->maccess,
+                  MGA_PLNWT,           ctx->plnwt,
+                  MGA_DWGCTL,          ctx->dwgctl );
 
-       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
-       PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
-       PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
-       PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
+       DMA_BLOCK( MGA_ALPHACTRL,       ctx->alphactrl,
+                  MGA_FOGCOL,          ctx->fogcolor,
+                  MGA_WFLAG,           ctx->wflag,
+                  MGA_ZORG,            dev_priv->depth_offset );
 
-       PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]);
-       PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]);
-       PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]);
-       PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]);
+       DMA_BLOCK( MGA_WFLAG1,          ctx->wflag,
+                  MGA_TDUALSTAGE0,     ctx->tdualstage0,
+                  MGA_TDUALSTAGE1,     ctx->tdualstage1,
+                  MGA_FCOL,            ctx->fcol );
 
-       PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
-       PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
-       PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-       PRIMOUTREG(MGAREG_WR49, 0);
+       DMA_BLOCK( MGA_STENCIL,         ctx->stencil,
+                  MGA_STENCILCTL,      ctx->stencilctl,
+                  MGA_DMAPAD,          0x00000000,
+                  MGA_DMAPAD,          0x00000000 );
 
-       PRIMOUTREG(MGAREG_WR57, 0);
-       PRIMOUTREG(MGAREG_WR53, 0);
-       PRIMOUTREG(MGAREG_WR61, 0);
-       PRIMOUTREG(MGAREG_WR52, 0x40);
-
-       PRIMOUTREG(MGAREG_WR60, 0x40);
-       PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40);
-       PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
-       PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
-
-       PRIMADVANCE(dev_priv);
+       ADVANCE_DMA();
 }
 
-#define TMC_map1_enable                0x80000000
-
-static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
+static inline void mga_g200_emit_tex0( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->TexState[1];
-       PRIMLOCALS;
+       drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
+       DMA_LOCALS;
 
-       PRIMGETPTR(dev_priv);
+       BEGIN_DMA( 4 );
 
-       /* This takes 25 dwords */
+       DMA_BLOCK( MGA_TEXCTL2,         tex->texctl2,
+                  MGA_TEXCTL,          tex->texctl,
+                  MGA_TEXFILTER,       tex->texfilter,
+                  MGA_TEXBORDERCOL,    tex->texbordercol );
 
-       PRIMOUTREG(MGAREG_TEXCTL2,
-                  regs[MGA_TEXREG_CTL2] | TMC_map1_enable | 0x00008000);
-       PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
-       PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
-       PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
+       DMA_BLOCK( MGA_TEXORG,          tex->texorg,
+                  MGA_TEXORG1,         tex->texorg1,
+                  MGA_TEXORG2,         tex->texorg2,
+                  MGA_TEXORG3,         tex->texorg3 );
 
-       PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG]);
-       PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1]);
-       PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2]);
-       PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3]);
+       DMA_BLOCK( MGA_TEXORG4,         tex->texorg4,
+                  MGA_TEXWIDTH,        tex->texwidth,
+                  MGA_TEXHEIGHT,       tex->texheight,
+                  MGA_WR24,            tex->texwidth );
 
-       PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
-       PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
-       PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
-       PRIMOUTREG(MGAREG_WR49, 0);
+       DMA_BLOCK( MGA_WR34,            tex->texheight,
+                  MGA_TEXTRANS,        0x0000ffff,
+                  MGA_TEXTRANSHIGH,    0x0000ffff,
+                  MGA_DMAPAD,          0x00000000 );
 
-       PRIMOUTREG(MGAREG_WR57, 0);
-       PRIMOUTREG(MGAREG_WR53, 0);
-       PRIMOUTREG(MGAREG_WR61, 0);
-       PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40);
-
-       PRIMOUTREG(MGAREG_WR60, regs[MGA_TEXREG_HEIGHT] | 0x40);
-       PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
-       PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
-       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
+       ADVANCE_DMA();
+}
 
-       PRIMADVANCE(dev_priv);
+static inline void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
+{
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
+       DMA_LOCALS;
+
+       BEGIN_DMA( 6 );
+
+       DMA_BLOCK( MGA_TEXCTL2,         tex->texctl2 | MGA_G400_TC2_MAGIC,
+                  MGA_TEXCTL,          tex->texctl,
+                  MGA_TEXFILTER,       tex->texfilter,
+                  MGA_TEXBORDERCOL,    tex->texbordercol );
+
+       DMA_BLOCK( MGA_TEXORG,          tex->texorg,
+                  MGA_TEXORG1,         tex->texorg1,
+                  MGA_TEXORG2,         tex->texorg2,
+                  MGA_TEXORG3,         tex->texorg3 );
+
+       DMA_BLOCK( MGA_TEXORG4,         tex->texorg4,
+                  MGA_TEXWIDTH,        tex->texwidth,
+                  MGA_TEXHEIGHT,       tex->texheight,
+                  MGA_WR49,            0x00000000 );
+
+       DMA_BLOCK( MGA_WR57,            0x00000000,
+                  MGA_WR53,            0x00000000,
+                  MGA_WR61,            0x00000000,
+                  MGA_WR52,            MGA_G400_WR_MAGIC );
+
+       DMA_BLOCK( MGA_WR60,            MGA_G400_WR_MAGIC,
+                  MGA_WR54,            tex->texwidth | MGA_G400_WR_MAGIC,
+                  MGA_WR62,            tex->texheight | MGA_G400_WR_MAGIC,
+                  MGA_DMAPAD,          0x00000000 );
+
+       DMA_BLOCK( MGA_DMAPAD,          0x00000000,
+                  MGA_DMAPAD,          0x00000000,
+                  MGA_TEXTRANS,        0x0000ffff,
+                  MGA_TEXTRANSHIGH,    0x0000ffff );
+
+       ADVANCE_DMA();
 }
 
-#define MAGIC_FPARAM_HEX_VALUE 0x46480000
-/* This is the hex value of 12800.0f which is a magic value we must
- * set in wr56.
- */
+static inline void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
+{
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
+       DMA_LOCALS;
+
+       BEGIN_DMA( 5 );
+
+       DMA_BLOCK( MGA_TEXCTL2,         (tex->texctl2 |
+                                        MGA_MAP1_ENABLE |
+                                        MGA_G400_TC2_MAGIC),
+                  MGA_TEXCTL,          tex->texctl,
+                  MGA_TEXFILTER,       tex->texfilter,
+                  MGA_TEXBORDERCOL,    tex->texbordercol );
+
+       DMA_BLOCK( MGA_TEXORG,          tex->texorg,
+                  MGA_TEXORG1,         tex->texorg1,
+                  MGA_TEXORG2,         tex->texorg2,
+                  MGA_TEXORG3,         tex->texorg3 );
+
+       DMA_BLOCK( MGA_TEXORG4,         tex->texorg4,
+                  MGA_TEXWIDTH,        tex->texwidth,
+                  MGA_TEXHEIGHT,       tex->texheight,
+                  MGA_WR49,            0x00000000 );
+
+       DMA_BLOCK( MGA_WR57,            0x00000000,
+                  MGA_WR53,            0x00000000,
+                  MGA_WR61,            0x00000000,
+                  MGA_WR52,            tex->texwidth | MGA_G400_WR_MAGIC );
+
+       DMA_BLOCK( MGA_WR60,            tex->texheight | MGA_G400_WR_MAGIC,
+                  MGA_TEXTRANS,        0x0000ffff,
+                  MGA_TEXTRANSHIGH,    0x0000ffff,
+                  MGA_TEXCTL2,         tex->texctl2 | MGA_G400_TC2_MAGIC );
+
+       ADVANCE_DMA();
+}
 
-static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
+static inline void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int pipe = sarea_priv->WarpPipe;
-       PRIMLOCALS;
+       unsigned int pipe = sarea_priv->warp_pipe;
+       DMA_LOCALS;
 
-       PRIMGETPTR(dev_priv);
+       BEGIN_DMA( 3 );
 
-       /* This takes 50 dwords */
+       DMA_BLOCK( MGA_WIADDR,  MGA_WMODE_SUSPEND,
+                  MGA_WVRTXSZ, 0x00000007,
+                  MGA_WFLAG,   0x00000000,
+                  MGA_WR24,    0x00000000 );
 
-       /* Establish vertex size.  
+       DMA_BLOCK( MGA_WR25,    0x00000100,
+                  MGA_WR34,    0x00000000,
+                  MGA_WR42,    0x0000ffff,
+                  MGA_WR60,    0x0000ffff );
+
+       /* Padding required to to hardware bug.
         */
-       PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-       if (pipe & MGA_T2) {
-               PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
+       DMA_BLOCK( MGA_DMAPAD,  0xffffffff,
+                  MGA_DMAPAD,  0xffffffff,
+                  MGA_DMAPAD,  0xffffffff,
+                  MGA_WIADDR,  (dev_priv->warp_pipe_phys[pipe] |
+                                MGA_WMODE_START |
+                                MGA_WAGP_ENABLE) );
+
+       ADVANCE_DMA();
+}
+
+static inline void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
+{
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       unsigned int pipe = sarea_priv->warp_pipe;
+       DMA_LOCALS;
+
+       BEGIN_DMA( 10 );
+
+       DMA_BLOCK( MGA_WIADDR2, MGA_WMODE_SUSPEND,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000 );
+
+       if ( pipe & MGA_T2 ) {
+               DMA_BLOCK( MGA_WVRTXSZ,         0x00001e09,
+                          MGA_DMAPAD,          0x00000000,
+                          MGA_DMAPAD,          0x00000000,
+                          MGA_DMAPAD,          0x00000000 );
+
+               DMA_BLOCK( MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x1e000000 );
        } else {
-               if (dev_priv->WarpPipe & MGA_T2) {
+               if ( dev_priv->warp_pipe & MGA_T2 ) {
                        /* Flush the WARP pipe */
-                       PRIMOUTREG(MGAREG_YDST, 0);
-                       PRIMOUTREG(MGAREG_FXLEFT, 0);
-                       PRIMOUTREG(MGAREG_FXRIGHT, 1);
-                       PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
-
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
-                       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-                       PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
-
-                       PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
-                       PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
+                       DMA_BLOCK( MGA_YDST,            0x00000000,
+                                  MGA_FXLEFT,          0x00000000,
+                                  MGA_FXRIGHT,         0x00000001,
+                                  MGA_DWGCTL,          MGA_DWGCTL_FLUSH );
+
+                       DMA_BLOCK( MGA_LEN + MGA_EXEC,  0x00000001,
+                                  MGA_DWGSYNC,         0x00007000,
+                                  MGA_TEXCTL2,         MGA_G400_TC2_MAGIC,
+                                  MGA_LEN + MGA_EXEC,  0x00000000 );
+
+                       DMA_BLOCK( MGA_TEXCTL2,         (MGA_DUALTEX |
+                                                        MGA_G400_TC2_MAGIC),
+                                  MGA_LEN + MGA_EXEC,  0x00000000,
+                                  MGA_TEXCTL2,         MGA_G400_TC2_MAGIC,
+                                  MGA_DMAPAD,          0x00000000 );
                }
 
-               PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
-               PRIMOUTREG(MGAREG_DMAPAD, 0);
+               DMA_BLOCK( MGA_WVRTXSZ,         0x00001807,
+                          MGA_DMAPAD,          0x00000000,
+                          MGA_DMAPAD,          0x00000000,
+                          MGA_DMAPAD,          0x00000000 );
 
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
-               PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
+               DMA_BLOCK( MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x00000000,
+                          MGA_WACCEPTSEQ,      0x18000000 );
        }
 
-       PRIMOUTREG(MGAREG_WFLAG, 0);
-       PRIMOUTREG(MGAREG_WFLAG1, 0);
-       PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-
-       PRIMOUTREG(MGAREG_WR49, 0);     /* Tex stage 0 */
-       PRIMOUTREG(MGAREG_WR57, 0);     /* Tex stage 0 */
-       PRIMOUTREG(MGAREG_WR53, 0);     /* Tex stage 1 */
-       PRIMOUTREG(MGAREG_WR61, 0);     /* Tex stage 1 */
-
-       PRIMOUTREG(MGAREG_WR54, 0x40);  /* Tex stage 0 : w */
-       PRIMOUTREG(MGAREG_WR62, 0x40);  /* Tex stage 0 : h */
-       PRIMOUTREG(MGAREG_WR52, 0x40);  /* Tex stage 1 : w */
-       PRIMOUTREG(MGAREG_WR60, 0x40);  /* Tex stage 1 : h */
-
-       /* Dma pading required due to hw bug */
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_WIADDR2,
-                  (u32) (dev_priv->WarpIndex[pipe].
-                         phys_addr | WIA_wmode_start | WIA_wagp_agp));
-       PRIMADVANCE(dev_priv);
+       DMA_BLOCK( MGA_WFLAG,   0x00000000,
+                  MGA_WFLAG1,  0x00000000,
+                  MGA_WR56,    MGA_G400_WR56_MAGIC,
+                  MGA_DMAPAD,  0x00000000 );
+
+       DMA_BLOCK( MGA_WR49,    0x00000000,             /* tex0              */
+                  MGA_WR57,    0x00000000,             /* tex0              */
+                  MGA_WR53,    0x00000000,             /* tex1              */
+                  MGA_WR61,    0x00000000 );           /* tex1              */
+
+       DMA_BLOCK( MGA_WR54,    MGA_G400_WR_MAGIC,      /* tex0 width        */
+                  MGA_WR62,    MGA_G400_WR_MAGIC,      /* tex0 height       */
+                  MGA_WR52,    MGA_G400_WR_MAGIC,      /* tex1 width        */
+                  MGA_WR60,    MGA_G400_WR_MAGIC );    /* tex1 height       */
+
+       /* Padding required to to hardware bug */
+       DMA_BLOCK( MGA_DMAPAD,  0xffffffff,
+                  MGA_DMAPAD,  0xffffffff,
+                  MGA_DMAPAD,  0xffffffff,
+                  MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] |
+                                MGA_WMODE_START |
+                                MGA_WAGP_ENABLE) );
+
+       ADVANCE_DMA();
 }
 
-static void mgaG200EmitPipe(drm_mga_private_t * dev_priv)
+static void mga_g200_emit_state( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int pipe = sarea_priv->WarpPipe;
-       PRIMLOCALS;
-
-       PRIMGETPTR(dev_priv);
-
-       /* This takes 15 dwords */
-
-       PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
-       PRIMOUTREG(MGAREG_WVRTXSZ, 7);
-       PRIMOUTREG(MGAREG_WFLAG, 0);
-       PRIMOUTREG(MGAREG_WR24, 0);     /* tex w/h */
+       unsigned int dirty = sarea_priv->dirty;
 
-       PRIMOUTREG(MGAREG_WR25, 0x100);
-       PRIMOUTREG(MGAREG_WR34, 0);     /* tex w/h */
-       PRIMOUTREG(MGAREG_WR42, 0xFFFF);
-       PRIMOUTREG(MGAREG_WR60, 0xFFFF);
+       if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
+               mga_g200_emit_pipe( dev_priv );
+               dev_priv->warp_pipe = sarea_priv->warp_pipe;
+       }
 
-       /* Dma pading required due to hw bug */
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_WIADDR,
-                  (u32) (dev_priv->WarpIndex[pipe].
-                         phys_addr | WIA_wmode_start | WIA_wagp_agp));
+       if ( dirty & MGA_UPLOAD_CONTEXT ) {
+               mga_g200_emit_context( dev_priv );
+               sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
+       }
 
-       PRIMADVANCE( dev_priv );
+       if ( dirty & MGA_UPLOAD_TEX0 ) {
+               mga_g200_emit_tex0( dev_priv );
+               sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+       }
 }
 
-static void mgaEmitState(drm_mga_private_t * dev_priv)
+static void mga_g400_emit_state( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
+       int multitex = sarea_priv->warp_pipe & MGA_T2;
 
-       if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
-               int multitex = sarea_priv->WarpPipe & MGA_T2;
-
-               if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
-                       mgaG400EmitPipe(dev_priv);
-                       dev_priv->WarpPipe = sarea_priv->WarpPipe;
-               }
-
-               if (dirty & MGA_UPLOAD_CTX) {
-                       mgaEmitContext(dev_priv);
-                       sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
-               }
-
-               if (dirty & MGA_UPLOAD_TEX0) {
-                       mgaG400EmitTex0(dev_priv);
-                       sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
-               }
+       if ( sarea_priv->warp_pipe != dev_priv->warp_pipe ) {
+               mga_g400_emit_pipe( dev_priv );
+               dev_priv->warp_pipe = sarea_priv->warp_pipe;
+       }
 
-               if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
-                       mgaG400EmitTex1(dev_priv);
-                       sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
-               }
-       } else {
-               if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
-                       mgaG200EmitPipe(dev_priv);
-                       dev_priv->WarpPipe = sarea_priv->WarpPipe;
-               }
+       if ( dirty & MGA_UPLOAD_CONTEXT ) {
+               mga_g400_emit_context( dev_priv );
+               sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
+       }
 
-               if (dirty & MGA_UPLOAD_CTX) {
-                       mgaEmitContext(dev_priv);
-                       sarea_priv->dirty &= ~MGA_UPLOAD_CTX;
-               }
+       if ( dirty & MGA_UPLOAD_TEX0 ) {
+               mga_g400_emit_tex0( dev_priv );
+               sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
+       }
 
-               if (dirty & MGA_UPLOAD_TEX0) {
-                       mgaG200EmitTex(dev_priv);
-                       sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
-               }
+       if ( (dirty & MGA_UPLOAD_TEX1) && multitex ) {
+               mga_g400_emit_tex1( dev_priv );
+               sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
        }
 }
 
+
+/* ================================================================
+ * SAREA state verification
+ */
+
 /* Disallow all write destinations except the front and backbuffer.
  */
-static int mgaVerifyContext(drm_mga_private_t * dev_priv)
+static int mga_verify_context( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-
-       if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
-           regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
-               DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
-                         regs[MGA_CTXREG_DSTORG], dev_priv->frontOffset,
-                         dev_priv->backOffset);
-               regs[MGA_CTXREG_DSTORG] = 0;
-               return -1;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+
+       if ( ctx->dstorg != dev_priv->front_offset &&
+            ctx->dstorg != dev_priv->back_offset ) {
+               DRM_ERROR( "*** bad DSTORG: %x (front %x, back %x)\n\n",
+                          ctx->dstorg, dev_priv->front_offset,
+                          dev_priv->back_offset );
+               ctx->dstorg = 0;
+               return -EINVAL;
        }
 
        return 0;
@@ -424,594 +420,668 @@ static int mgaVerifyContext(drm_mga_private_t * dev_priv)
 
 /* Disallow texture reads from PCI space.
  */
-static int mgaVerifyTex(drm_mga_private_t * dev_priv, int unit)
+static int mga_verify_tex( drm_mga_private_t *dev_priv, int unit )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
+       unsigned int org;
+
+       org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
 
-       if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
-               DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
-                         sarea_priv->TexState[unit][MGA_TEXREG_ORG],
-                         unit);
-               sarea_priv->TexState[unit][MGA_TEXREG_ORG] = 0;
-               return -1;
+       if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) {
+               DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n",
+                          tex->texorg, unit );
+               tex->texorg = 0;
+               return -EINVAL;
        }
 
        return 0;
 }
 
-static int mgaVerifyState(drm_mga_private_t * dev_priv)
+static int mga_verify_state( drm_mga_private_t *dev_priv )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int dirty = sarea_priv->dirty;
-       int rv = 0;
+       int ret = 0;
 
-       if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+       if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 
-       if (dirty & MGA_UPLOAD_CTX)
-               rv |= mgaVerifyContext(dev_priv);
+       if ( dirty & MGA_UPLOAD_CONTEXT )
+               ret |= mga_verify_context( dev_priv );
 
-       if (dirty & MGA_UPLOAD_TEX0)
-               rv |= mgaVerifyTex(dev_priv, 0);
+       if ( dirty & MGA_UPLOAD_TEX0 )
+               ret |= mga_verify_tex( dev_priv, 0 );
 
-       if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
-               if (dirty & MGA_UPLOAD_TEX1)
-                       rv |= mgaVerifyTex(dev_priv, 1);
+       if ( dev_priv->chipset == MGA_CARD_TYPE_G400 ) {
+               if ( dirty & MGA_UPLOAD_TEX1 )
+                       ret |= mga_verify_tex( dev_priv, 1 );
 
-               if (dirty & MGA_UPLOAD_PIPE)
-                       rv |= (sarea_priv->WarpPipe > MGA_MAX_G400_PIPES);
+               if ( dirty & MGA_UPLOAD_PIPE )
+                       ret |= ( sarea_priv->warp_pipe > MGA_MAX_G400_PIPES );
        } else {
-               if (dirty & MGA_UPLOAD_PIPE)
-                       rv |= (sarea_priv->WarpPipe > MGA_MAX_G200_PIPES);
+               if ( dirty & MGA_UPLOAD_PIPE )
+                       ret |= ( sarea_priv->warp_pipe > MGA_MAX_G200_PIPES );
        }
 
-       return rv == 0;
+       return ( ret == 0 );
 }
 
-static int mgaVerifyIload(drm_mga_private_t * dev_priv,
-                         unsigned long bus_address,
-                         unsigned int dstOrg, int length)
+static int mga_verify_iload( drm_mga_private_t *dev_priv,
+                            unsigned int dstorg, unsigned int length )
 {
-       if (dstOrg < dev_priv->textureOffset ||
-           dstOrg + length >
-           (dev_priv->textureOffset + dev_priv->textureSize)) {
+       if ( dstorg < dev_priv->texture_offset ||
+            dstorg + length > (dev_priv->texture_offset +
+                               dev_priv->texture_size) ) {
+               DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg );
                return -EINVAL;
        }
-       if (length % 64) {
+
+       if ( length & MGA_ILOAD_MASK ) {
+               DRM_ERROR( "*** bad iload length: 0x%x\n",
+                          length & MGA_ILOAD_MASK );
                return -EINVAL;
        }
+
        return 0;
 }
 
-/* This copies a 64 byte aligned agp region to the frambuffer
- * with a standard blit, the ioctl needs to do checking */
+static int mga_verify_blit( drm_mga_private_t *dev_priv,
+                           unsigned int srcorg, unsigned int dstorg )
+{
+       if ( (srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
+            (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) {
+               DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n",
+                          srcorg, dstorg );
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+/* ================================================================
+ *
+ */
 
-static void mga_dma_dispatch_tex_blit(drm_device_t * dev,
-                                     unsigned long bus_address,
-                                     int length, unsigned int destOrg)
+static void mga_dma_dispatch_clear( drm_device_t *dev,
+                                   drm_mga_clear_t *clear )
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
-       int use_agp = PDEA_pagpxfer_enable | 0x00000001;
-       u16 y2;
-       PRIMLOCALS;
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       drm_clip_rect_t *pbox = sarea_priv->boxes;
+       int nbox = sarea_priv->nbox;
+       int i;
+       DMA_LOCALS;
+       DRM_DEBUG( __FUNCTION__ ":\n" );
 
-       y2 = length / 64;
+       BEGIN_DMA( 1 );
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGSYNC, 0x00007100,
+                  MGA_DWGSYNC, 0x00007000 );
+
+       ADVANCE_DMA();
 
-       PRIM_OVERFLOW(dev, dev_priv, 30);
+       for ( i = 0 ; i < nbox ; i++ ) {
+               drm_clip_rect_t *box = &pbox[i];
+               u32 height = box->y2 - box->y1;
 
-       PRIMOUTREG(MGAREG_DSTORG, destOrg);
-       PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
-       PRIMOUTREG(MGAREG_SRCORG, (u32) bus_address | use_agp);
-       PRIMOUTREG(MGAREG_AR5, 64);
+               DRM_DEBUG( "   from=%d,%d to=%d,%d\n",
+                          box->x1, box->y1, box->x2, box->y2 );
 
-       PRIMOUTREG(MGAREG_PITCH, 64);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+               if ( clear->flags & MGA_FRONT ) {
+                       BEGIN_DMA( 2 );
 
-       PRIMOUTREG(MGAREG_AR0, 63);
-       PRIMOUTREG(MGAREG_AR3, 0);
-       PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
-       PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_PLNWT,   clear->color_mask,
+                                  MGA_YDSTLEN, (box->y1 << 16) | height,
+                                  MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
 
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_SRCORG, 0);
-       PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-       PRIMADVANCE(dev_priv);
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_FCOL,    clear->clear_color,
+                                  MGA_DSTORG,  dev_priv->front_offset,
+                                  MGA_DWGCTL + MGA_EXEC,
+                                               dev_priv->clear_cmd );
+
+                       ADVANCE_DMA();
+               }
+
+
+               if ( clear->flags & MGA_BACK ) {
+                       BEGIN_DMA( 2 );
+
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_PLNWT,   clear->color_mask,
+                                  MGA_YDSTLEN, (box->y1 << 16) | height,
+                                  MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_FCOL,    clear->clear_color,
+                                  MGA_DSTORG,  dev_priv->back_offset,
+                                  MGA_DWGCTL + MGA_EXEC,
+                                               dev_priv->clear_cmd );
+
+                       ADVANCE_DMA();
+               }
+
+               if ( clear->flags & MGA_DEPTH ) {
+                       BEGIN_DMA( 2 );
+
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_PLNWT,   clear->depth_mask,
+                                  MGA_YDSTLEN, (box->y1 << 16) | height,
+                                  MGA_FXBNDRY, (box->x2 << 16) | box->x1 );
+
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_FCOL,    clear->clear_depth,
+                                  MGA_DSTORG,  dev_priv->depth_offset,
+                                  MGA_DWGCTL + MGA_EXEC,
+                                               dev_priv->clear_cmd );
+
+                       ADVANCE_DMA();
+               }
+
+       }
+
+       BEGIN_DMA( 1 );
+
+       /* Force reset of DWGCTL */
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_PLNWT,   ctx->plnwt,
+                  MGA_DWGCTL,  ctx->dwgctl );
+
+       ADVANCE_DMA();
+
+       FLUSH_DMA();
+}
+
+static void mga_dma_dispatch_swap( drm_device_t *dev )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       drm_clip_rect_t *pbox = sarea_priv->boxes;
+       int nbox = sarea_priv->nbox;
+       int i;
+       DMA_LOCALS;
+       DRM_DEBUG( __FUNCTION__ ":\n" );
+
+       sarea_priv->last_frame.head = dev_priv->prim.tail;
+       sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
+
+       BEGIN_DMA( 4 + nbox );
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGSYNC, 0x00007100,
+                  MGA_DWGSYNC, 0x00007000 );
+
+       DMA_BLOCK( MGA_DSTORG,  dev_priv->front_offset,
+                  MGA_MACCESS, dev_priv->maccess,
+                  MGA_SRCORG,  dev_priv->back_offset,
+                  MGA_AR5,     dev_priv->front_pitch );
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_PLNWT,   0xffffffff,
+                  MGA_DWGCTL,  MGA_DWGCTL_COPY );
+
+       for ( i = 0 ; i < nbox ; i++ ) {
+               drm_clip_rect_t *box = &pbox[i];
+               u32 height = box->y2 - box->y1;
+               u32 start = box->y1 * dev_priv->front_pitch;
+
+               DRM_DEBUG( "   from=%d,%d to=%d,%d\n",
+                          box->x1, box->y1, box->x2, box->y2 );
+
+               DMA_BLOCK( MGA_AR0,     start + box->x2 - 1,
+                          MGA_AR3,     start + box->x1,
+                          MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
+                          MGA_YDSTLEN + MGA_EXEC,
+                                       (box->y1 << 16) | height );
+       }
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_PLNWT,   ctx->plnwt,
+                  MGA_SRCORG,  dev_priv->front_offset,
+                  MGA_DWGCTL,  ctx->dwgctl );
+
+       ADVANCE_DMA();
+
+       FLUSH_DMA();
+
+       DRM_DEBUG( "%s... done.\n", __FUNCTION__ );
 }
 
-static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
+static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_buf_priv_t *buf_priv = buf->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned long address = (unsigned long) buf->bus_address;
-       int length = buf->used;
-       int use_agp = PDEA_pagpxfer_enable;
+       u32 address = (u32) buf->bus_address;
+       u32 length = (u32) buf->used;
        int i = 0;
-       PRIMLOCALS;
+       DMA_LOCALS;
+       DRM_DEBUG( "vertex: buf=%d used=%d\n", buf->idx, buf->used );
 
-       if (buf->used) {
-               /* WARNING: if you change any of the state functions verify
-                * these numbers (Overestimating this doesn't hurt).
-                */
+       if ( buf->used ) {
                buf_priv->dispatched = 1;
-               PRIM_OVERFLOW(dev, dev_priv,
-                             (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
-               mgaEmitState(dev_priv);
 
-#if 0
-               length = dev_priv->vertexsize * 3 * 4;
-#endif
+               MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
 
                do {
-                       if (i < sarea_priv->nbox) {
-                               mgaEmitClipRect(dev_priv,
-                                               &sarea_priv->boxes[i]);
+                       if ( i < sarea_priv->nbox ) {
+                               mga_emit_clip_rect( dev_priv,
+                                                   &sarea_priv->boxes[i] );
                        }
 
-                       PRIMGETPTR(dev_priv);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_SECADDRESS,
-                                  ((u32) address) | TT_VERTEX);
-                       PRIMOUTREG(MGAREG_SECEND,
-                                  (((u32) (address + length)) | use_agp));
-                       PRIMADVANCE(dev_priv);
-               } while (++i < sarea_priv->nbox);
+                       BEGIN_DMA( 1 );
+
+                       DMA_BLOCK( MGA_DMAPAD,          0x00000000,
+                                  MGA_DMAPAD,          0x00000000,
+                                  MGA_SECADDRESS,      (address |
+                                                        MGA_DMA_VERTEX),
+                                  MGA_SECEND,          ((address + length) |
+                                                        MGA_PAGPXFER) );
+
+                       ADVANCE_DMA();
+               } while ( ++i < sarea_priv->nbox );
        }
-       if (buf_priv->discard) {
-               if (buf_priv->dispatched == 1)
-                       AGEBUF(dev_priv, buf_priv);
+
+       if ( buf_priv->discard ) {
+               AGE_BUFFER( buf_priv );
+               buf->pending = 0;
+               buf->used = 0;
                buf_priv->dispatched = 0;
-               mga_freelist_put(dev, buf);
-       }
 
+               mga_freelist_put( dev, buf );
+       }
 
+       FLUSH_DMA();
 }
 
-
-static void mga_dma_dispatch_indices(drm_device_t * dev,
-                                    drm_buf_t * buf,
-                                    unsigned int start, unsigned int end)
+static void mga_dma_dispatch_indices( drm_device_t *dev, drm_buf_t *buf,
+                                     unsigned int start, unsigned int end )
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_buf_priv_t *buf_priv = buf->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int address = (unsigned int) buf->bus_address;
-       int use_agp = PDEA_pagpxfer_enable;
+       u32 address = (u32) buf->bus_address;
        int i = 0;
-       PRIMLOCALS;
+       DMA_LOCALS;
+       DRM_DEBUG( "indices: buf=%d start=%d end=%d\n", buf->idx, start, end );
 
-       if (start != end) {
-               /* WARNING: if you change any of the state functions verify
-                * these numbers (Overestimating this doesn't hurt).
-                */
+       if ( start != end ) {
                buf_priv->dispatched = 1;
-               PRIM_OVERFLOW(dev, dev_priv,
-                             (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
-               mgaEmitState(dev_priv);
+
+               MGA_EMIT_STATE( dev_priv, sarea_priv->dirty );
 
                do {
-                       if (i < sarea_priv->nbox) {
-                               mgaEmitClipRect(dev_priv,
-                                               &sarea_priv->boxes[i]);
+                       if ( i < sarea_priv->nbox ) {
+                               mga_emit_clip_rect( dev_priv,
+                                                   &sarea_priv->boxes[i] );
                        }
 
-                       PRIMGETPTR(dev_priv);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_SETUPADDRESS,
-                                  ((address + start) |
-                                   SETADD_mode_vertlist));
-                       PRIMOUTREG(MGAREG_SETUPEND,
-                                  ((address + end) | use_agp));
-/*                                ((address + start + 12) | use_agp)); */
-                       PRIMADVANCE(dev_priv);
-               } while (++i < sarea_priv->nbox);
+                       BEGIN_DMA( 1 );
+
+                       DMA_BLOCK( MGA_DMAPAD,          0x00000000,
+                                  MGA_DMAPAD,          0x00000000,
+                                  MGA_SETUPADDRESS,    address + start,
+                                  MGA_SETUPEND,        ((address + end) |
+                                                        MGA_PAGPXFER) );
+
+                       ADVANCE_DMA();
+               } while ( ++i < sarea_priv->nbox );
        }
-       if (buf_priv->discard) {
-               if (buf_priv->dispatched == 1)
-                       AGEBUF(dev_priv, buf_priv);
+
+       if ( buf_priv->discard ) {
+               AGE_BUFFER( buf_priv );
+               buf->pending = 0;
+               buf->used = 0;
                buf_priv->dispatched = 0;
-               mga_freelist_put(dev, buf);
+
+               mga_freelist_put( dev, buf );
        }
-}
 
+       FLUSH_DMA();
+}
 
-static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
-                                  unsigned int clear_color,
-                                  unsigned int clear_zval,
-                                  unsigned int clear_colormask,
-                                  unsigned int clear_depthmask)
+/* This copies a 64 byte aligned agp region to the frambuffer with a
+ * standard blit, the ioctl needs to do checking.
+ */
+static void mga_dma_dispatch_iload( drm_device_t *dev, drm_buf_t *buf,
+                                   unsigned int dstorg, unsigned int length )
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
-       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-       int nbox = sarea_priv->nbox;
-       drm_clip_rect_t *pbox = sarea_priv->boxes;
-       unsigned int cmd;
-       int i;
-       PRIMLOCALS;
-
-       if (dev_priv->sgram)
-               cmd = MGA_CLEAR_CMD | DC_atype_blk;
-       else
-               cmd = MGA_CLEAR_CMD | DC_atype_rstr;
-
-       PRIM_OVERFLOW(dev, dev_priv, 35 * MGA_NR_SAREA_CLIPRECTS);
-
-       for (i = 0; i < nbox; i++) {
-               unsigned int height = pbox[i].y2 - pbox[i].y1;
-
-               if (flags & MGA_FRONT) {
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
-                       PRIMOUTREG(MGAREG_YDSTLEN,
-                                  (pbox[i].y1 << 16) | height);
-                       PRIMOUTREG(MGAREG_FXBNDRY,
-                                  (pbox[i].x2 << 16) | pbox[i].x1);
-
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_FCOL, clear_color);
-                       PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
-                       PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);
-               }
+       drm_mga_buf_priv_t *buf_priv = buf->dev_private;
+       drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
+       u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM;
+       u32 y2;
+       DMA_LOCALS;
+       DRM_DEBUG( "%s: buf=%d used=%d\n",
+                  __FUNCTION__, buf->idx, buf->used );
 
-               if (flags & MGA_BACK) {
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
-                       PRIMOUTREG(MGAREG_YDSTLEN,
-                                  (pbox[i].y1 << 16) | height);
-                       PRIMOUTREG(MGAREG_FXBNDRY,
-                                  (pbox[i].x2 << 16) | pbox[i].x1);
-
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_FCOL, clear_color);
-                       PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);
-                       PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);
-               }
+       y2 = length / 64;
 
-               if (flags & MGA_DEPTH) {
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);
-                       PRIMOUTREG(MGAREG_YDSTLEN,
-                                  (pbox[i].y1 << 16) | height);
-                       PRIMOUTREG(MGAREG_FXBNDRY,
-                                  (pbox[i].x2 << 16) | pbox[i].x1);
-
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_FCOL, clear_zval);
-                       PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);
-                       PRIMOUTREG(MGAREG_DWGCTL + MGAREG_MGA_EXEC, cmd);
-               }
-       }
+       BEGIN_DMA( 5 );
 
-       /* Force reset of DWGCTL */
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-       PRIMADVANCE(dev_priv);
-}
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGSYNC, 0x00007100,
+                  MGA_DWGSYNC, 0x00007000 );
 
-static void mga_dma_dispatch_swap(drm_device_t * dev)
-{
-       drm_mga_private_t *dev_priv = dev->dev_private;
-       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-       int nbox = sarea_priv->nbox;
-       drm_clip_rect_t *pbox = sarea_priv->boxes;
-       int i;
-       int pixel_stride = dev_priv->stride / dev_priv->cpp;
+       DMA_BLOCK( MGA_DSTORG,  dstorg,
+                  MGA_MACCESS, 0x00000000,
+                  MGA_SRCORG,  srcorg,
+                  MGA_AR5,     64 );
+
+       DMA_BLOCK( MGA_PITCH,   64,
+                  MGA_PLNWT,   0xffffffff,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGCTL,  MGA_DWGCTL_COPY );
+
+       DMA_BLOCK( MGA_AR0,     63,
+                  MGA_AR3,     0,
+                  MGA_FXBNDRY, (63 << 16) | 0,
+                  MGA_YDSTLEN + MGA_EXEC, y2 );
 
-       PRIMLOCALS;
+       DMA_BLOCK( MGA_PLNWT,   ctx->plnwt,
+                  MGA_SRCORG,  dev_priv->front_offset,
+                  MGA_PITCH,   dev_priv->front_pitch,
+                  MGA_DWGSYNC, 0x00007000 );
 
-       PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
+       ADVANCE_DMA();
 
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
+       AGE_BUFFER( buf_priv );
 
-       PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
-       PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
-       PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
-       PRIMOUTREG(MGAREG_AR5, pixel_stride);
+       buf->pending = 0;
+       buf->used = 0;
+       buf_priv->dispatched = 0;
 
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+       mga_freelist_put( dev, buf );
+
+       FLUSH_DMA();
+}
+
+static void mga_dma_dispatch_blit( drm_device_t *dev,
+                                  drm_mga_blit_t *blit )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
+       drm_clip_rect_t *pbox = sarea_priv->boxes;
+       int nbox = sarea_priv->nbox;
+       u32 scandir = 0, i;
+       DMA_LOCALS;
+       DRM_DEBUG( __FUNCTION__ ":\n" );
+
+       BEGIN_DMA( 4 + nbox );
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGSYNC, 0x00007100,
+                  MGA_DWGSYNC, 0x00007000 );
+
+       DMA_BLOCK( MGA_DWGCTL,  MGA_DWGCTL_COPY,
+                  MGA_PLNWT,   blit->planemask,
+                  MGA_SRCORG,  blit->srcorg,
+                  MGA_DSTORG,  blit->dstorg );
+
+       DMA_BLOCK( MGA_SGN,     scandir,
+                  MGA_MACCESS, dev_priv->maccess,
+                  MGA_AR5,     blit->ydir * blit->src_pitch,
+                  MGA_PITCH,   blit->dst_pitch );
+
+       for ( i = 0 ; i < nbox ; i++ ) {
+               int srcx = pbox[i].x1 + blit->delta_sx;
+               int srcy = pbox[i].y1 + blit->delta_sy;
+               int dstx = pbox[i].x1 + blit->delta_dx;
+               int dsty = pbox[i].y1 + blit->delta_dy;
+               int h = pbox[i].y2 - pbox[i].y1;
+               int w = pbox[i].x2 - pbox[i].x1 - 1;
+               int start;
+
+               if ( blit->ydir == -1 ) {
+                       srcy = blit->height - srcy - 1;
+               }
 
-       for (i = 0; i < nbox; i++) {
-               unsigned int h = pbox[i].y2 - pbox[i].y1;
-               unsigned int start = pbox[i].y1 * pixel_stride;
+               start = srcy * blit->src_pitch + srcx;
 
-               PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
-               PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
-               PRIMOUTREG(MGAREG_FXBNDRY,
-                          pbox[i].x1 | ((pbox[i].x2 - 1) << 16));
-               PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC,
-                          (pbox[i].y1 << 16) | h);
+               DMA_BLOCK( MGA_AR0,     start + w,
+                          MGA_AR3,     start,
+                          MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
+                          MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h );
        }
 
+       /* Do something to flush AGP?
+        */
+
        /* Force reset of DWGCTL */
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_SRCORG, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_PLNWT,   ctx->plnwt,
+                  MGA_PITCH,   dev_priv->front_pitch,
+                  MGA_DWGCTL,  ctx->dwgctl );
 
-       PRIMADVANCE(dev_priv);
+       ADVANCE_DMA();
 }
 
-int mga_clear_bufs(struct inode *inode, struct file *filp,
-                  unsigned int cmd, unsigned long arg)
+
+/* ================================================================
+ *
+ */
+
+int mga_dma_clear( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-       drm_mga_private_t *dev_priv =
-           (drm_mga_private_t *) dev->dev_private;
+       drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_mga_clear_t clear;
 
-       if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear)))
-               return -EFAULT;
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_clear_bufs called without lock held\n");
-               return -EINVAL;
-       }
+       if ( copy_from_user( &clear, (drm_mga_clear_t *) arg, sizeof(clear) ) )
+               return -EFAULT;
 
-       if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+       if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 
+       WRAP_TEST_WITH_RETURN( dev_priv );
+
+       mga_dma_dispatch_clear( dev, &clear );
+
        /* Make sure we restore the 3D state next time.
         */
-       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
-       mga_dma_dispatch_clear(dev, clear.flags,
-                              clear.clear_color,
-                              clear.clear_depth,
-                              clear.clear_color_mask,
-                              clear.clear_depth_mask);
-       PRIMUPDATE(dev_priv);
-       mga_flush_write_combine();
-       mga_dma_schedule(dev, 1);
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
+
        return 0;
 }
 
-int mga_swap_bufs(struct inode *inode, struct file *filp,
-                 unsigned int cmd, unsigned long arg)
+int mga_dma_swap( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-       drm_mga_private_t *dev_priv =
-           (drm_mga_private_t *) dev->dev_private;
+       drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_swap_bufs called without lock held\n");
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
+       if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 
+       WRAP_TEST_WITH_RETURN( dev_priv );
+
+       mga_dma_dispatch_swap( dev );
+
        /* Make sure we restore the 3D state next time.
         */
-       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
-       mga_dma_dispatch_swap(dev);
-       PRIMUPDATE(dev_priv);
-       set_bit(MGA_BUF_SWAP_PENDING,
-               &dev_priv->current_prim->buffer_status);
-       mga_flush_write_combine();
-       mga_dma_schedule(dev, 1);
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
+
        return 0;
 }
 
-int mga_iload(struct inode *inode, struct file *filp,
-             unsigned int cmd, unsigned long arg)
+int mga_dma_vertex( struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
+       drm_mga_private_t *dev_priv = dev->dev_private;
        drm_device_dma_t *dma = dev->dma;
-       drm_mga_private_t *dev_priv =
-           (drm_mga_private_t *) dev->dev_private;
-       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_buf_t *buf;
        drm_mga_buf_priv_t *buf_priv;
-       drm_mga_iload_t iload;
-       unsigned long bus_address;
+       drm_mga_vertex_t vertex;
 
-       if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload)))
-               return -EFAULT;
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_iload called without lock held\n");
-               return -EINVAL;
-       }
+       if ( copy_from_user( &vertex,
+                            (drm_mga_vertex_t *)arg,
+                            sizeof(vertex) ) )
+               return -EFAULT;
 
-       if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL;
-       buf = dma->buflist[iload.idx];
+        if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+       buf = dma->buflist[vertex.idx];
        buf_priv = buf->dev_private;
-       bus_address = buf->bus_address;
 
-       if (mgaVerifyIload(dev_priv,
-                          bus_address, iload.destOrg, iload.length)) {
-               mga_freelist_put(dev, buf);
+       buf->used = vertex.used;
+       buf_priv->discard = vertex.discard;
+
+       if ( !mga_verify_state( dev_priv ) ) {
+               if ( vertex.discard ) {
+                       if ( buf_priv->dispatched == 1 )
+                               AGE_BUFFER( buf_priv );
+                       buf_priv->dispatched = 0;
+                       mga_freelist_put( dev, buf );
+               }
                return -EINVAL;
        }
 
-       sarea_priv->dirty |= MGA_UPLOAD_CTX;
+       WRAP_TEST_WITH_RETURN( dev_priv );
+
+       mga_dma_dispatch_vertex( dev, buf );
 
-       mga_dma_dispatch_tex_blit(dev, bus_address, iload.length,
-                                 iload.destOrg);
-       AGEBUF(dev_priv, buf_priv);
-       buf_priv->discard = 1;
-       mga_freelist_put(dev, buf);
-       mga_flush_write_combine();
-       mga_dma_schedule(dev, 1);
        return 0;
 }
 
-int mga_vertex(struct inode *inode, struct file *filp,
-              unsigned int cmd, unsigned long arg)
+int mga_dma_indices( struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-       drm_mga_private_t *dev_priv =
-           (drm_mga_private_t *) dev->dev_private;
+       drm_mga_private_t *dev_priv = dev->dev_private;
        drm_device_dma_t *dma = dev->dma;
        drm_buf_t *buf;
        drm_mga_buf_priv_t *buf_priv;
-       drm_mga_vertex_t vertex;
+       drm_mga_indices_t indices;
 
-       if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex)))
-               return -EFAULT;
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_vertex called without lock held\n");
-               return -EINVAL;
-       }
+       if ( copy_from_user( &indices,
+                            (drm_mga_indices_t *)arg,
+                            sizeof(indices) ) )
+               return -EFAULT;
 
-       if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+        if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;
 
-       buf = dma->buflist[vertex.idx];
+       buf = dma->buflist[indices.idx];
        buf_priv = buf->dev_private;
 
-       buf->used = vertex.used;
-       buf_priv->discard = vertex.discard;
+       buf_priv->discard = indices.discard;
 
-       if (!mgaVerifyState(dev_priv)) {
-               if (vertex.discard) {
-                       if (buf_priv->dispatched == 1)
-                               AGEBUF(dev_priv, buf_priv);
+       if ( !mga_verify_state( dev_priv ) ) {
+               if ( indices.discard ) {
+                       if ( buf_priv->dispatched == 1 )
+                               AGE_BUFFER( buf_priv );
                        buf_priv->dispatched = 0;
-                       mga_freelist_put(dev, buf);
+                       mga_freelist_put( dev, buf );
                }
                return -EINVAL;
        }
 
-       mga_dma_dispatch_vertex(dev, buf);
+       WRAP_TEST_WITH_RETURN( dev_priv );
+
+       mga_dma_dispatch_indices( dev, buf, indices.start, indices.end );
 
-       PRIMUPDATE(dev_priv);
-       mga_flush_write_combine();
-       mga_dma_schedule(dev, 1);
        return 0;
 }
 
-
-int mga_indices(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg)
+int mga_dma_iload( struct inode *inode, struct file *filp,
+                  unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-       drm_mga_private_t *dev_priv =
-           (drm_mga_private_t *) dev->dev_private;
        drm_device_dma_t *dma = dev->dma;
+       drm_mga_private_t *dev_priv = dev->dev_private;
        drm_buf_t *buf;
        drm_mga_buf_priv_t *buf_priv;
-       drm_mga_indices_t indices;
+       drm_mga_iload_t iload;
+       DRM_DEBUG( __FUNCTION__ ":\n" );
 
-       if (copy_from_user(&indices,
-                          (drm_mga_indices_t *)arg, sizeof(indices)))
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) )
                return -EFAULT;
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_indices called without lock held\n");
-               return -EINVAL;
+#if 0
+       if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
+               if ( MGA_DMA_DEBUG )
+                       DRM_INFO( __FUNCTION__": -EBUSY\n" );
+               return -EBUSY;
        }
+#endif
+        if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL;
 
-       if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;
-       buf = dma->buflist[indices.idx];
+       buf = dma->buflist[iload.idx];
        buf_priv = buf->dev_private;
 
-       buf_priv->discard = indices.discard;
-
-       if (!mgaVerifyState(dev_priv)) {
-               if (indices.discard) {
-                       if (buf_priv->dispatched == 1)
-                               AGEBUF(dev_priv, buf_priv);
-                       buf_priv->dispatched = 0;
-                       mga_freelist_put(dev, buf);
-               }
+       if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) {
+               mga_freelist_put( dev, buf );
                return -EINVAL;
        }
 
-       mga_dma_dispatch_indices(dev, buf, indices.start, indices.end);
-
-       PRIMUPDATE(dev_priv);
-       mga_flush_write_combine();
-       mga_dma_schedule(dev, 1);
-       return 0;
-}
+       WRAP_TEST_WITH_RETURN( dev_priv );
 
+       mga_dma_dispatch_iload( dev, buf, iload.dstorg, iload.length );
 
+       /* Make sure we restore the 3D state next time.
+        */
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 
-static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d)
-{
-       int i;
-       drm_buf_t *buf;
-
-       for (i = d->granted_count; i < d->request_count; i++) {
-               buf = mga_freelist_get(dev);
-               if (!buf)
-                       break;
-               buf->pid = current->pid;
-               if (copy_to_user(&d->request_indices[i],
-                                &buf->idx, sizeof(buf->idx)))
-                       return -EFAULT;
-               if (copy_to_user(&d->request_sizes[i],
-                                &buf->total, sizeof(buf->total)))
-                       return -EFAULT;
-               ++d->granted_count;
-       }
        return 0;
 }
 
-int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
-           unsigned long arg)
+int mga_dma_blit( struct inode *inode, struct file *filp,
+                 unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
-       drm_device_dma_t *dma = dev->dma;
-       int retcode = 0;
-       drm_dma_t d;
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
+       drm_mga_blit_t blit;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d)))
+       if ( copy_from_user( &blit, (drm_mga_blit_t *)arg, sizeof(blit) ) )
                return -EFAULT;
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_dma called without lock held\n");
-               return -EINVAL;
-       }
+       if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
+               sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 
-       /* Please don't send us buffers.
-        */
-       if (d.send_count != 0) {
-               DRM_ERROR
-                   ("Process %d trying to send %d buffers via drmDMA\n",
-                    current->pid, d.send_count);
+       if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) )
                return -EINVAL;
-       }
 
-       /* We'll send you buffers.
-        */
-       if (d.request_count < 0 || d.request_count > dma->buf_count) {
-               DRM_ERROR
-                   ("Process %d trying to get %d buffers (of %d max)\n",
-                    current->pid, d.request_count, dma->buf_count);
-               return -EINVAL;
-       }
+       WRAP_TEST_WITH_RETURN( dev_priv );
 
-       d.granted_count = 0;
+       mga_dma_dispatch_blit( dev, &blit );
 
-       if (d.request_count) {
-               retcode = mga_dma_get_buffers(dev, &d);
-       }
+       /* Make sure we restore the 3D state next time.
+        */
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 
-       if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d)))
-               return -EFAULT;
-       return retcode;
+       return 0;
 }
diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h
new file mode 100644 (file)
index 0000000..fa0f82e
--- /dev/null
@@ -0,0 +1,11645 @@
+/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*-
+ * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com
+ *
+ * Copyright 1999 Matrox Graphics Inc.
+ * 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 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
+ * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS 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.
+ *
+ * Kernel-based WARP engine management:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+/*
+ * WARP pipes are named according to the functions they perform, where:
+ *
+ *   - T stands for computation of texture stage 0
+ *   - T2 stands for computation of both texture stage 0 and texture stage 1
+ *   - G stands for computation of triangle intensity (Gouraud interpolation)
+ *   - Z stands for computation of Z buffer interpolation
+ *   - S stands for computation of specular highlight
+ *   - A stands for computation of the alpha channel
+ *   - F stands for computation of vertex fog interpolation
+ */
+
+static unsigned char warp_g200_tgz[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x72, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x60, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x03, 0x80, 0x0A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x57, 0x39, 0x20, 0xE9,
+0x28, 0x19, 0x60, 0xEC,
+
+0x2B, 0x32, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0xB3, 0x05,
+0x00, 0xE0,
+0x16, 0x28, 0x20, 0xE9,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x1E, 0x2B, 0x20, 0xE9,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x85, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x84, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x82, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x7F, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgza[] = {
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x7D, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x6B, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2D, 0x44, 0x4C, 0xB6,
+0x25, 0x44, 0x54, 0xB6,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x07, 0xC0, 0x44, 0xC6,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x1F, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x3F, 0x3D, 0x5D, 0x9F,
+0x00, 0xE0,
+0x07, 0x20,
+
+0x00, 0x80, 0x00, 0xE8,
+0x28, 0x19, 0x60, 0xEC,
+
+0xB3, 0x05,
+0x00, 0xE0,
+0x00, 0x80, 0x00, 0xE8,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0x26, 0x1F, 0xDF,
+0x9D, 0x1F, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x9E, 0x3F, 0x4F, 0xE9,
+
+0x07, 0x07, 0x1F, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x9C, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x7A, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x79, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x77, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x74, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzaf[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x83, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x6F, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0D, 0x21, 0x1A, 0xB6,
+0x05, 0x21, 0x31, 0xB6,
+
+0x2D, 0x44, 0x4C, 0xB6,
+0x25, 0x44, 0x54, 0xB6,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x0D, 0x20,
+0x05, 0x20,
+0x2F, 0xC0, 0x21, 0xC6,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x07, 0xC0, 0x44, 0xC6,
+
+0x17, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x2D, 0x20,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x1F, 0x62, 0x57, 0x9F,
+0x00, 0xE0,
+0x07, 0x20,
+
+0x3F, 0x3D, 0x5D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x28, 0x19, 0x60, 0xEC,
+
+0xB3, 0x05,
+0x00, 0xE0,
+0x17, 0x26, 0x17, 0xDF,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x35, 0x17, 0x4F, 0xE9,
+
+0x1F, 0x26, 0x1F, 0xDF,
+0x9D, 0x1F, 0x4F, 0xE9,
+
+0x9E, 0x3F, 0x4F, 0xE9,
+0x39, 0x37, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x17, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0x07, 0x07, 0x1F, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0x31, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x9C, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x74, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x73, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x71, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6E, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzf[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x7F, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x6B, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0D, 0x21, 0x1A, 0xB6,
+0x05, 0x21, 0x31, 0xB6,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x0D, 0x20,
+0x05, 0x20,
+0x2F, 0xC0, 0x21, 0xC6,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x17, 0x50, 0x56, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x00, 0x80, 0x00, 0xE8,
+0x28, 0x19, 0x60, 0xEC,
+
+0xB3, 0x05,
+0x00, 0xE0,
+0x00, 0x80, 0x00, 0xE8,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x17, 0x26, 0x17, 0xDF,
+0x35, 0x17, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x39, 0x37, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x17, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x31, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x78, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x77, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x75, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x72, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzs[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x8B, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x77, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2D, 0x21, 0x1A, 0xB0,
+0x25, 0x21, 0x31, 0xB0,
+
+0x0D, 0x21, 0x1A, 0xB2,
+0x05, 0x21, 0x31, 0xB2,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x05, 0x20,
+0x0D, 0x20,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x2F, 0xC0, 0x21, 0xC0,
+
+0x16, 0x42, 0x56, 0x9F,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x1E, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x21, 0x31, 0xB4,
+0x2D, 0x21, 0x1A, 0xB4,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0x05,
+0x00, 0xE0,
+0x28, 0x19, 0x60, 0xEC,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x1E, 0x26, 0x1E, 0xDF,
+
+0xA7, 0x1E, 0x4F, 0xE9,
+0x17, 0x26, 0x16, 0xDF,
+
+0x2D, 0x20,
+0x00, 0xE0,
+0xA8, 0x3F, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x1E, 0xAF,
+0x25, 0x20,
+0x00, 0xE0,
+
+0xA4, 0x16, 0x4F, 0xE9,
+0x0F, 0xC0, 0x21, 0xC2,
+
+0xA6, 0x80, 0x4F, 0xE9,
+0x1F, 0x62, 0x57, 0x9F,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0xE0,
+0x8F, 0x20,
+
+0xA5, 0x37, 0x4F, 0xE9,
+0x0F, 0x17, 0x0F, 0xAF,
+
+0x06, 0xC0, 0x21, 0xC4,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0xA3, 0x80, 0x4F, 0xE9,
+
+0x06, 0x20,
+0x00, 0xE0,
+0x1F, 0x26, 0x1F, 0xDF,
+
+0xA1, 0x1F, 0x4F, 0xE9,
+0xA2, 0x3F, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x06, 0x06, 0x1F, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x6C, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6B, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x69, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzsa[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x8F, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x7B, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2D, 0x21, 0x1A, 0xB0,
+0x25, 0x21, 0x31, 0xB0,
+
+0x0D, 0x21, 0x1A, 0xB2,
+0x05, 0x21, 0x31, 0xB2,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x05, 0x20,
+0x0D, 0x20,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x2F, 0xC0, 0x21, 0xC0,
+
+0x16, 0x42, 0x56, 0x9F,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x1E, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x21, 0x31, 0xB4,
+0x2D, 0x21, 0x1A, 0xB4,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0x05,
+0x00, 0xE0,
+0x28, 0x19, 0x60, 0xEC,
+
+0x0D, 0x44, 0x4C, 0xB6,
+0x05, 0x44, 0x54, 0xB6,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x1E, 0x26, 0x1E, 0xDF,
+
+0xA7, 0x1E, 0x4F, 0xE9,
+0x17, 0x26, 0x16, 0xDF,
+
+0x2D, 0x20,
+0x00, 0xE0,
+0xA8, 0x3F, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x1E, 0xAF,
+0x25, 0x20,
+0x00, 0xE0,
+
+0xA4, 0x16, 0x4F, 0xE9,
+0x0F, 0xC0, 0x21, 0xC2,
+
+0xA6, 0x80, 0x4F, 0xE9,
+0x1F, 0x62, 0x57, 0x9F,
+
+0x0D, 0x20,
+0x05, 0x20,
+0x00, 0x80, 0x00, 0xE8,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0xE0,
+0x0F, 0x20,
+
+0x17, 0x50, 0x56, 0x9F,
+0xA5, 0x37, 0x4F, 0xE9,
+
+0x06, 0xC0, 0x21, 0xC4,
+0x0F, 0x17, 0x0F, 0xAF,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2F, 0xC0, 0x44, 0xC6,
+0xA3, 0x80, 0x4F, 0xE9,
+
+0x06, 0x20,
+0x00, 0xE0,
+0x1F, 0x26, 0x1F, 0xDF,
+
+0x17, 0x26, 0x17, 0xDF,
+0x9D, 0x17, 0x4F, 0xE9,
+
+0xA1, 0x1F, 0x4F, 0xE9,
+0xA2, 0x3F, 0x4F, 0xE9,
+
+0x06, 0x06, 0x1F, 0xAF,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x9E, 0x37, 0x4F, 0xE9,
+0x2F, 0x17, 0x2F, 0xAF,
+
+0xA0, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x9C, 0x80, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x68, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x67, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x65, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x62, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzsaf[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x94, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x80, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2D, 0x21, 0x1A, 0xB0,
+0x25, 0x21, 0x31, 0xB0,
+
+0x0D, 0x21, 0x1A, 0xB2,
+0x05, 0x21, 0x31, 0xB2,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x05, 0x20,
+0x0D, 0x20,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x2F, 0xC0, 0x21, 0xC0,
+
+0x16, 0x42, 0x56, 0x9F,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x1E, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x21, 0x31, 0xB4,
+0x2D, 0x21, 0x1A, 0xB4,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0x05,
+0x00, 0xE0,
+0x28, 0x19, 0x60, 0xEC,
+
+0x0D, 0x21, 0x1A, 0xB6,
+0x05, 0x21, 0x31, 0xB6,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x1E, 0x26, 0x1E, 0xDF,
+
+0xA7, 0x1E, 0x4F, 0xE9,
+0x17, 0x26, 0x16, 0xDF,
+
+0x2D, 0x20,
+0x00, 0xE0,
+0xA8, 0x3F, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x1E, 0xAF,
+0x25, 0x20,
+0x00, 0xE0,
+
+0xA4, 0x16, 0x4F, 0xE9,
+0x0F, 0xC0, 0x21, 0xC2,
+
+0xA6, 0x80, 0x4F, 0xE9,
+0x1F, 0x62, 0x57, 0x9F,
+
+0x0D, 0x20,
+0x05, 0x20,
+0x2F, 0xC0, 0x21, 0xC6,
+
+0x2D, 0x44, 0x4C, 0xB6,
+0x25, 0x44, 0x54, 0xB6,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0xE0,
+0x0F, 0x20,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x07, 0xC0, 0x44, 0xC6,
+
+0x17, 0x50, 0x56, 0x9F,
+0xA5, 0x37, 0x4F, 0xE9,
+
+0x06, 0xC0, 0x21, 0xC4,
+0x0F, 0x17, 0x0F, 0xAF,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1E, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x3E, 0x3D, 0x5D, 0x9F,
+0x00, 0xE0,
+0x07, 0x20,
+
+0x2F, 0x20,
+0x00, 0xE0,
+0xA3, 0x0F, 0x4F, 0xE9,
+
+0x06, 0x20,
+0x00, 0xE0,
+0x1F, 0x26, 0x1F, 0xDF,
+
+0x17, 0x26, 0x17, 0xDF,
+0xA1, 0x1F, 0x4F, 0xE9,
+
+0x1E, 0x26, 0x1E, 0xDF,
+0x9D, 0x1E, 0x4F, 0xE9,
+
+0x35, 0x17, 0x4F, 0xE9,
+0xA2, 0x3F, 0x4F, 0xE9,
+
+0x06, 0x06, 0x1F, 0xAF,
+0x39, 0x37, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x17, 0xAF,
+0x07, 0x07, 0x1E, 0xAF,
+
+0xA0, 0x80, 0x4F, 0xE9,
+0x9E, 0x3E, 0x4F, 0xE9,
+
+0x31, 0x80, 0x4F, 0xE9,
+0x9C, 0x80, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x63, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x62, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x60, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x5D, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g200_tgzsf[] = {
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x98, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x81, 0x04,
+0x89, 0x04,
+0x01, 0x04,
+0x09, 0x04,
+
+0xC9, 0x41, 0xC0, 0xEC,
+0x11, 0x04,
+0x00, 0xE0,
+
+0x41, 0xCC, 0x41, 0xCD,
+0x49, 0xCC, 0x49, 0xCD,
+
+0xD1, 0x41, 0xC0, 0xEC,
+0x51, 0xCC, 0x51, 0xCD,
+
+0x80, 0x04,
+0x10, 0x04,
+0x08, 0x04,
+0x00, 0xE0,
+
+0x00, 0xCC, 0xC0, 0xCD,
+0xD1, 0x49, 0xC0, 0xEC,
+
+0x8A, 0x1F, 0x20, 0xE9,
+0x8B, 0x3F, 0x20, 0xE9,
+
+0x41, 0x3C, 0x41, 0xAD,
+0x49, 0x3C, 0x49, 0xAD,
+
+0x10, 0xCC, 0x10, 0xCD,
+0x08, 0xCC, 0x08, 0xCD,
+
+0xB9, 0x41, 0x49, 0xBB,
+0x1F, 0xF0, 0x41, 0xCD,
+
+0x51, 0x3C, 0x51, 0xAD,
+0x00, 0x98, 0x80, 0xE9,
+
+0x8F, 0x80, 0x07, 0xEA,
+0x24, 0x1F, 0x20, 0xE9,
+
+0x21, 0x45, 0x80, 0xE8,
+0x1A, 0x4D, 0x80, 0xE8,
+
+0x31, 0x55, 0x80, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0x41, 0x49, 0xBD,
+0x1D, 0x41, 0x51, 0xBD,
+
+0x2E, 0x41, 0x2A, 0xB8,
+0x34, 0x53, 0xA0, 0xE8,
+
+0x15, 0x30,
+0x1D, 0x30,
+0x58, 0xE3,
+0x00, 0xE0,
+
+0xB5, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x24, 0x43, 0xA0, 0xE8,
+0x2C, 0x4B, 0xA0, 0xE8,
+
+0x15, 0x72,
+0x09, 0xE3,
+0x00, 0xE0,
+0x1D, 0x72,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0x97, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x6C, 0x64, 0xC8, 0xEC,
+0x98, 0xE1,
+0xB5, 0x05,
+
+0xBD, 0x05,
+0x2E, 0x30,
+0x32, 0xC0, 0xA0, 0xE8,
+
+0x33, 0xC0, 0xA0, 0xE8,
+0x74, 0x64, 0xC8, 0xEC,
+
+0x40, 0x3C, 0x40, 0xAD,
+0x32, 0x6A,
+0x2A, 0x30,
+
+0x20, 0x73,
+0x33, 0x6A,
+0x00, 0xE0,
+0x28, 0x73,
+
+0x1C, 0x72,
+0x83, 0xE2,
+0x7B, 0x80, 0x15, 0xEA,
+
+0xB8, 0x3D, 0x28, 0xDF,
+0x30, 0x35, 0x20, 0xDF,
+
+0x40, 0x30,
+0x00, 0xE0,
+0xCC, 0xE2,
+0x64, 0x72,
+
+0x25, 0x42, 0x52, 0xBF,
+0x2D, 0x42, 0x4A, 0xBF,
+
+0x30, 0x2E, 0x30, 0xDF,
+0x38, 0x2E, 0x38, 0xDF,
+
+0x18, 0x1D, 0x45, 0xE9,
+0x1E, 0x15, 0x45, 0xE9,
+
+0x2B, 0x49, 0x51, 0xBD,
+0x00, 0xE0,
+0x1F, 0x73,
+
+0x38, 0x38, 0x40, 0xAF,
+0x30, 0x30, 0x40, 0xAF,
+
+0x24, 0x1F, 0x24, 0xDF,
+0x1D, 0x32, 0x20, 0xE9,
+
+0x2C, 0x1F, 0x2C, 0xDF,
+0x1A, 0x33, 0x20, 0xE9,
+
+0xB0, 0x10,
+0x08, 0xE3,
+0x40, 0x10,
+0xB8, 0x10,
+
+0x26, 0xF0, 0x30, 0xCD,
+0x2F, 0xF0, 0x38, 0xCD,
+
+0x2B, 0x80, 0x20, 0xE9,
+0x2A, 0x80, 0x20, 0xE9,
+
+0xA6, 0x20,
+0x88, 0xE2,
+0x00, 0xE0,
+0xAF, 0x20,
+
+0x28, 0x2A, 0x26, 0xAF,
+0x20, 0x2A, 0xC0, 0xAF,
+
+0x34, 0x1F, 0x34, 0xDF,
+0x46, 0x24, 0x46, 0xDF,
+
+0x28, 0x30, 0x80, 0xBF,
+0x20, 0x38, 0x80, 0xBF,
+
+0x47, 0x24, 0x47, 0xDF,
+0x4E, 0x2C, 0x4E, 0xDF,
+
+0x4F, 0x2C, 0x4F, 0xDF,
+0x56, 0x34, 0x56, 0xDF,
+
+0x28, 0x15, 0x28, 0xDF,
+0x20, 0x1D, 0x20, 0xDF,
+
+0x57, 0x34, 0x57, 0xDF,
+0x00, 0xE0,
+0x1D, 0x05,
+
+0x04, 0x80, 0x10, 0xEA,
+0x89, 0xE2,
+0x2B, 0x30,
+
+0x3F, 0xC1, 0x1D, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x68,
+0xBF, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x20, 0xC0, 0x20, 0xAF,
+0x28, 0x05,
+0x97, 0x74,
+
+0x00, 0xE0,
+0x2A, 0x10,
+0x16, 0xC0, 0x20, 0xE9,
+
+0x04, 0x80, 0x10, 0xEA,
+0x8C, 0xE2,
+0x95, 0x05,
+
+0x28, 0xC1, 0x28, 0xAD,
+0x1F, 0xC1, 0x15, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA8, 0x67,
+0x9F, 0x6B,
+0x00, 0x80, 0x00, 0xE8,
+
+0x28, 0xC0, 0x28, 0xAD,
+0x1D, 0x25,
+0x20, 0x05,
+
+0x28, 0x32, 0x80, 0xAD,
+0x40, 0x2A, 0x40, 0xBD,
+
+0x1C, 0x80, 0x20, 0xE9,
+0x20, 0x33, 0x20, 0xAD,
+
+0x20, 0x73,
+0x00, 0xE0,
+0xB6, 0x49, 0x51, 0xBB,
+
+0x26, 0x2F, 0xB0, 0xE8,
+0x19, 0x20, 0x20, 0xE9,
+
+0x35, 0x20, 0x35, 0xDF,
+0x3D, 0x20, 0x3D, 0xDF,
+
+0x15, 0x20, 0x15, 0xDF,
+0x1D, 0x20, 0x1D, 0xDF,
+
+0x26, 0xD0, 0x26, 0xCD,
+0x29, 0x49, 0x2A, 0xB8,
+
+0x26, 0x40, 0x80, 0xBD,
+0x3B, 0x48, 0x50, 0xBD,
+
+0x3E, 0x54, 0x57, 0x9F,
+0x00, 0xE0,
+0x82, 0xE1,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x26, 0x30,
+0x29, 0x30,
+0x48, 0x3C, 0x48, 0xAD,
+
+0x2B, 0x72,
+0xC2, 0xE1,
+0x2C, 0xC0, 0x44, 0xC2,
+
+0x05, 0x24, 0x34, 0xBF,
+0x0D, 0x24, 0x2C, 0xBF,
+
+0x2D, 0x46, 0x4E, 0xBF,
+0x25, 0x46, 0x56, 0xBF,
+
+0x20, 0x1D, 0x6F, 0x8F,
+0x32, 0x3E, 0x5F, 0xE9,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x30,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x33, 0x1E, 0x5F, 0xE9,
+
+0x05, 0x44, 0x54, 0xB2,
+0x0D, 0x44, 0x4C, 0xB2,
+
+0x19, 0xC0, 0xB0, 0xE8,
+0x34, 0xC0, 0x44, 0xC4,
+
+0x33, 0x73,
+0x00, 0xE0,
+0x3E, 0x62, 0x57, 0x9F,
+
+0x1E, 0xAF, 0x59, 0x9F,
+0x00, 0xE0,
+0x0D, 0x20,
+
+0x84, 0x3E, 0x58, 0xE9,
+0x28, 0x1D, 0x6F, 0x8F,
+
+0x05, 0x20,
+0x00, 0xE0,
+0x85, 0x1E, 0x58, 0xE9,
+
+0x9B, 0x3B, 0x33, 0xDF,
+0x20, 0x20, 0x42, 0xAF,
+
+0x30, 0x42, 0x56, 0x9F,
+0x80, 0x3E, 0x57, 0xE9,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x30, 0x80, 0x5F, 0xE9,
+
+0x28, 0x28, 0x24, 0xAF,
+0x81, 0x1E, 0x57, 0xE9,
+
+0x05, 0x47, 0x57, 0xBF,
+0x0D, 0x47, 0x4F, 0xBF,
+
+0x88, 0x80, 0x58, 0xE9,
+0x1B, 0x29, 0x1B, 0xDF,
+
+0x30, 0x1D, 0x6F, 0x8F,
+0x3A, 0x30, 0x4F, 0xE9,
+
+0x1C, 0x30, 0x26, 0xDF,
+0x09, 0xE3,
+0x3B, 0x05,
+
+0x3E, 0x50, 0x56, 0x9F,
+0x3B, 0x3F, 0x4F, 0xE9,
+
+0x1E, 0x8F, 0x51, 0x9F,
+0x00, 0xE0,
+0xAC, 0x20,
+
+0x2D, 0x44, 0x4C, 0xB4,
+0x2C, 0x1C, 0xC0, 0xAF,
+
+0x25, 0x44, 0x54, 0xB4,
+0x00, 0xE0,
+0xC8, 0x30,
+
+0x30, 0x46, 0x30, 0xAF,
+0x1B, 0x1B, 0x48, 0xAF,
+
+0x00, 0xE0,
+0x25, 0x20,
+0x38, 0x2C, 0x4F, 0xE9,
+
+0x86, 0x80, 0x57, 0xE9,
+0x38, 0x1D, 0x6F, 0x8F,
+
+0x28, 0x74,
+0x00, 0xE0,
+0x0D, 0x44, 0x4C, 0xB0,
+
+0x05, 0x44, 0x54, 0xB0,
+0x2D, 0x20,
+0x9B, 0x10,
+
+0x82, 0x3E, 0x57, 0xE9,
+0x32, 0xF0, 0x1B, 0xCD,
+
+0x1E, 0xBD, 0x59, 0x9F,
+0x83, 0x1E, 0x57, 0xE9,
+
+0x38, 0x47, 0x38, 0xAF,
+0x34, 0x20,
+0x2A, 0x30,
+
+0x00, 0xE0,
+0x0D, 0x20,
+0x32, 0x20,
+0x05, 0x20,
+
+0x87, 0x80, 0x57, 0xE9,
+0x1F, 0x54, 0x57, 0x9F,
+
+0x17, 0x42, 0x56, 0x9F,
+0x00, 0xE0,
+0x3B, 0x6A,
+
+0x3F, 0x8F, 0x51, 0x9F,
+0x37, 0x1E, 0x4F, 0xE9,
+
+0x37, 0x32, 0x2A, 0xAF,
+0x00, 0xE0,
+0x32, 0x00,
+
+0x00, 0x80, 0x00, 0xE8,
+0x27, 0xC0, 0x44, 0xC0,
+
+0x36, 0x1F, 0x4F, 0xE9,
+0x1F, 0x1F, 0x26, 0xDF,
+
+0x37, 0x1B, 0x37, 0xBF,
+0x17, 0x26, 0x17, 0xDF,
+
+0x3E, 0x17, 0x4F, 0xE9,
+0x3F, 0x3F, 0x4F, 0xE9,
+
+0x34, 0x1F, 0x34, 0xAF,
+0x2B, 0x05,
+0xA7, 0x20,
+
+0x33, 0x2B, 0x37, 0xDF,
+0x27, 0x17, 0xC0, 0xAF,
+
+0x34, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2D, 0x21, 0x1A, 0xB0,
+0x25, 0x21, 0x31, 0xB0,
+
+0x0D, 0x21, 0x1A, 0xB2,
+0x05, 0x21, 0x31, 0xB2,
+
+0x03, 0x80, 0x2A, 0xEA,
+0x17, 0xC1, 0x2B, 0xBD,
+
+0x2D, 0x20,
+0x25, 0x20,
+0x05, 0x20,
+0x0D, 0x20,
+
+0xB3, 0x68,
+0x97, 0x25,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0xC0, 0x33, 0xAF,
+0x2F, 0xC0, 0x21, 0xC0,
+
+0x16, 0x42, 0x56, 0x9F,
+0x3C, 0x27, 0x4F, 0xE9,
+
+0x1E, 0x62, 0x57, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x21, 0x31, 0xB4,
+0x2D, 0x21, 0x1A, 0xB4,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x33, 0x05,
+0x00, 0xE0,
+0x28, 0x19, 0x60, 0xEC,
+
+0x0D, 0x21, 0x1A, 0xB6,
+0x05, 0x21, 0x31, 0xB6,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0xE0,
+0x2F, 0x20,
+
+0x23, 0x3B, 0x33, 0xAD,
+0x1E, 0x26, 0x1E, 0xDF,
+
+0xA7, 0x1E, 0x4F, 0xE9,
+0x17, 0x26, 0x16, 0xDF,
+
+0x2D, 0x20,
+0x00, 0xE0,
+0xA8, 0x3F, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x1E, 0xAF,
+0x25, 0x20,
+0x00, 0xE0,
+
+0xA4, 0x16, 0x4F, 0xE9,
+0x0F, 0xC0, 0x21, 0xC2,
+
+0xA6, 0x80, 0x4F, 0xE9,
+0x1F, 0x62, 0x57, 0x9F,
+
+0x0D, 0x20,
+0x05, 0x20,
+0x2F, 0xC0, 0x21, 0xC6,
+
+0x3F, 0x2F, 0x5D, 0x9F,
+0x00, 0xE0,
+0x0F, 0x20,
+
+0x17, 0x50, 0x56, 0x9F,
+0xA5, 0x37, 0x4F, 0xE9,
+
+0x06, 0xC0, 0x21, 0xC4,
+0x0F, 0x17, 0x0F, 0xAF,
+
+0x37, 0x0F, 0x5C, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2F, 0x20,
+0x00, 0xE0,
+0xA3, 0x80, 0x4F, 0xE9,
+
+0x06, 0x20,
+0x00, 0xE0,
+0x1F, 0x26, 0x1F, 0xDF,
+
+0x17, 0x26, 0x17, 0xDF,
+0x35, 0x17, 0x4F, 0xE9,
+
+0xA1, 0x1F, 0x4F, 0xE9,
+0xA2, 0x3F, 0x4F, 0xE9,
+
+0x06, 0x06, 0x1F, 0xAF,
+0x39, 0x37, 0x4F, 0xE9,
+
+0x2F, 0x2F, 0x17, 0xAF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xA0, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x31, 0x80, 0x4F, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x57, 0x39, 0x20, 0xE9,
+
+0x16, 0x28, 0x20, 0xE9,
+0x1D, 0x3B, 0x20, 0xE9,
+
+0x1E, 0x2B, 0x20, 0xE9,
+0x2B, 0x32, 0x20, 0xE9,
+
+0x1C, 0x23, 0x20, 0xE9,
+0x57, 0x36, 0x20, 0xE9,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x40, 0x40, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x90, 0xE2,
+0x00, 0xE0,
+
+0x68, 0xFF, 0x20, 0xEA,
+0x19, 0xC8, 0xC1, 0xCD,
+
+0x1F, 0xD7, 0x18, 0xBD,
+0x3F, 0xD7, 0x22, 0xBD,
+
+0x9F, 0x41, 0x49, 0xBD,
+0x00, 0x80, 0x00, 0xE8,
+
+0x25, 0x41, 0x49, 0xBD,
+0x2D, 0x41, 0x51, 0xBD,
+
+0x0D, 0x80, 0x07, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x35, 0x40, 0x48, 0xBD,
+0x3D, 0x40, 0x50, 0xBD,
+
+0x00, 0x80, 0x00, 0xE8,
+0x25, 0x30,
+0x2D, 0x30,
+
+0x35, 0x30,
+0xB5, 0x30,
+0xBD, 0x30,
+0x3D, 0x30,
+
+0x9C, 0xA7, 0x5B, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x67, 0xFF, 0x0A, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC9, 0x41, 0xC8, 0xEC,
+0x42, 0xE1,
+0x00, 0xE0,
+
+0x65, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0xC8, 0x40, 0xC0, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x62, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+};
+
+static unsigned char warp_g400_t2gz[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x78, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x69, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x25, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2A, 0x44, 0x54, 0xB4,
+0x1A, 0x44, 0x64, 0xB4,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x9F, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xBE, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x7D, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gza[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x7C, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x6D, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x29, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0F, 0xCF, 0x74, 0xC6,
+0x3D, 0xCF, 0x74, 0xC2,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x0F, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB4,
+0x02, 0x44, 0x64, 0xB4,
+
+0x2A, 0x44, 0x54, 0xB6,
+0x1A, 0x44, 0x64, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x9B, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xBA, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x79, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzaf[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x81, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x72, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x37, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x2E, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x0F, 0xCF, 0x74, 0xC6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x0F, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB4,
+0x02, 0x44, 0x64, 0xB4,
+
+0x2A, 0x44, 0x54, 0xB6,
+0x1A, 0x44, 0x64, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x3D, 0xCF, 0x75, 0xC6,
+0x00, 0x80, 0x00, 0xE8,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x45, 0x55, 0xB6,
+0x02, 0x45, 0x65, 0xB6,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x3D, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x96, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xB5, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x74, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzf[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x7D, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x6E, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0F, 0xCF, 0x75, 0xC6,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x28, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x31, 0x0F, 0x20, 0xE9,
+
+0x0A, 0x44, 0x54, 0xB4,
+0x02, 0x44, 0x64, 0xB4,
+
+0x2A, 0x45, 0x55, 0xB6,
+0x1A, 0x45, 0x65, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x9A, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xBB, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x78, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzs[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x85, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x76, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x0F, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x31, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0F, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB4,
+0x1A, 0x44, 0x64, 0xB4,
+
+0x0A, 0x45, 0x55, 0xB0,
+0x02, 0x45, 0x65, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x55, 0xB2,
+0x1A, 0x45, 0x65, 0xB2,
+
+0x0A, 0x45, 0x55, 0xB4,
+0x02, 0x45, 0x65, 0xB4,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x20,
+0x1A, 0x20,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA7, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x92, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xB2, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x70, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzsa[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x8A, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x7B, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x0F, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x36, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0F, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB4,
+0x1A, 0x44, 0x64, 0xB4,
+
+0x0A, 0x45, 0x55, 0xB0,
+0x02, 0x45, 0x65, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x55, 0xB2,
+0x1A, 0x45, 0x65, 0xB2,
+
+0x0A, 0x45, 0x55, 0xB4,
+0x02, 0x45, 0x65, 0xB4,
+
+0x0F, 0xCF, 0x74, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB6,
+0x1A, 0x44, 0x64, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x8D, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xAD, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x6B, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzsaf[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x8E, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x7F, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x0F, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x3A, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0F, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB4,
+0x1A, 0x44, 0x64, 0xB4,
+
+0x0A, 0x45, 0x55, 0xB0,
+0x02, 0x45, 0x65, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x55, 0xB2,
+0x1A, 0x45, 0x65, 0xB2,
+
+0x0A, 0x45, 0x55, 0xB4,
+0x02, 0x45, 0x65, 0xB4,
+
+0x0F, 0xCF, 0x74, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB6,
+0x1A, 0x44, 0x64, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x45, 0x55, 0xB6,
+0x02, 0x45, 0x65, 0xB6,
+
+0x3D, 0xCF, 0x75, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x31, 0x3D, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x89, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xA9, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x67, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_t2gzsf[] = {
+
+0x00, 0x8A, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x0A, 0x40, 0x50, 0xBF,
+0x2A, 0x40, 0x60, 0xBF,
+
+0x32, 0x41, 0x51, 0xBF,
+0x3A, 0x41, 0x61, 0xBF,
+
+0xC3, 0x6B,
+0xD3, 0x6B,
+0x00, 0x8A, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x53, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x23, 0x9F,
+0x00, 0xE0,
+0x51, 0x04,
+
+0x90, 0xE2,
+0x61, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x51, 0x41, 0xE0, 0xEC,
+0x39, 0x67, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x63, 0xA0, 0xE8,
+
+0x61, 0x41, 0xE0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x8A, 0x80, 0x15, 0xEA,
+0x10, 0x04,
+0x20, 0x04,
+
+0x61, 0x51, 0xE0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x52, 0xBF,
+0x0F, 0x52, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x62, 0xBF,
+0x1E, 0x51, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x0E, 0x61, 0x60, 0xEA,
+
+0x32, 0x40, 0x50, 0xBD,
+0x22, 0x40, 0x60, 0xBD,
+
+0x12, 0x41, 0x51, 0xBD,
+0x3A, 0x41, 0x61, 0xBD,
+
+0xBF, 0x2F, 0x0E, 0xBD,
+0x97, 0xE2,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x35, 0x48, 0xB1, 0xE8,
+0x3D, 0x59, 0xB1, 0xE8,
+
+0x46, 0x31, 0x46, 0xBF,
+0x56, 0x31, 0x56, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x66, 0x31, 0x66, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x57, 0x39, 0x57, 0xBF,
+0x67, 0x39, 0x67, 0xBF,
+
+0x7B, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x35, 0x00,
+0x3D, 0x00,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0x8D, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x75, 0xF8, 0xEC,
+0x35, 0x20,
+0x3D, 0x20,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x53, 0x53, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x0E, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x48, 0x35, 0x48, 0xBF,
+0x58, 0x35, 0x58, 0xBF,
+
+0x68, 0x35, 0x68, 0xBF,
+0x49, 0x3D, 0x49, 0xBF,
+
+0x59, 0x3D, 0x59, 0xBF,
+0x69, 0x3D, 0x69, 0xBF,
+
+0x63, 0x63, 0x2D, 0xDF,
+0x4D, 0x7D, 0xF8, 0xEC,
+
+0x59, 0xE3,
+0x00, 0xE0,
+0xB8, 0x38, 0x33, 0xBF,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x18, 0x3A, 0x41, 0xE9,
+
+0x3F, 0x53, 0xA0, 0xE8,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x63, 0xA0, 0xE8,
+
+0x50, 0x70, 0xF8, 0xEC,
+0x2B, 0x50, 0x3C, 0xE9,
+
+0x1F, 0x0F, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x59, 0x78, 0xF8, 0xEC,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x46, 0x37, 0x46, 0xDF,
+0x56, 0x3F, 0x56, 0xDF,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x66, 0x3D, 0x66, 0xDF,
+
+0x1D, 0x32, 0x41, 0xE9,
+0x67, 0x3D, 0x67, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3F, 0x57, 0xDF,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x59, 0x3F, 0x59, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x69, 0x3D, 0x69, 0xDF,
+
+0x48, 0x37, 0x48, 0xDF,
+0x58, 0x3F, 0x58, 0xDF,
+
+0x68, 0x3D, 0x68, 0xDF,
+0x49, 0x37, 0x49, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x0F, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x54, 0xB0,
+0x02, 0x44, 0x64, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB2,
+0x1A, 0x44, 0x64, 0xB2,
+
+0x36, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0F, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x54, 0xB4,
+0x1A, 0x44, 0x64, 0xB4,
+
+0x0A, 0x45, 0x55, 0xB0,
+0x02, 0x45, 0x65, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x55, 0xB2,
+0x1A, 0x45, 0x65, 0xB2,
+
+0x0A, 0x45, 0x55, 0xB4,
+0x02, 0x45, 0x65, 0xB4,
+
+0x0F, 0xCF, 0x75, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x31, 0x0F, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x55, 0xB6,
+0x1A, 0x45, 0x65, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x56, 0xBF,
+0x1A, 0x46, 0x66, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x57, 0xBF,
+0x02, 0x47, 0x67, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x53, 0xBF,
+0x1A, 0x43, 0x63, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x48, 0x58, 0xBF,
+0x02, 0x48, 0x68, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x2A, 0x49, 0x59, 0xBF,
+0x1A, 0x49, 0x69, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x82, 0x30, 0x57, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x83, 0x38, 0x57, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x84, 0x31, 0x5E, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x85, 0x39, 0x5E, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x87, 0x77, 0x57, 0xE9,
+0x8B, 0x3E, 0xBF, 0xEA,
+
+0x80, 0x30, 0x57, 0xE9,
+0x81, 0x38, 0x57, 0xE9,
+
+0x82, 0x31, 0x57, 0xE9,
+0x86, 0x78, 0x57, 0xE9,
+
+0x83, 0x39, 0x57, 0xE9,
+0x87, 0x79, 0x57, 0xE9,
+
+0x30, 0x1F, 0x5F, 0xE9,
+0x8A, 0x34, 0x20, 0xE9,
+
+0x8B, 0x3C, 0x20, 0xE9,
+0x37, 0x50, 0x60, 0xBD,
+
+0x57, 0x0D, 0x20, 0xE9,
+0x35, 0x51, 0x61, 0xBD,
+
+0x2B, 0x50, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x0E, 0x77,
+
+0x24, 0x51, 0x20, 0xE9,
+0x8D, 0xFF, 0x20, 0xEA,
+
+0x16, 0x0E, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x0B, 0x46, 0xA0, 0xE8,
+0x1B, 0x56, 0xA0, 0xE8,
+
+0x2B, 0x66, 0xA0, 0xE8,
+0x0C, 0x47, 0xA0, 0xE8,
+
+0x1C, 0x57, 0xA0, 0xE8,
+0x2C, 0x67, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x57, 0x80, 0x57, 0xCF,
+
+0x66, 0x33, 0x66, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x67, 0x3B, 0x67, 0xCF,
+
+0x0B, 0x48, 0xA0, 0xE8,
+0x1B, 0x58, 0xA0, 0xE8,
+
+0x2B, 0x68, 0xA0, 0xE8,
+0x0C, 0x49, 0xA0, 0xE8,
+
+0x1C, 0x59, 0xA0, 0xE8,
+0x2C, 0x69, 0xA0, 0xE8,
+
+0x0B, 0x00,
+0x1B, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x0C, 0x00,
+0x1C, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x0B, 0x65,
+0x1B, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x0C, 0x65,
+0x1C, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x0B, 0x1B, 0x60, 0xEC,
+0x34, 0xD7, 0x34, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x0C, 0x1C, 0x60, 0xEC,
+
+0x3C, 0xD7, 0x3C, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x0B, 0x2B, 0xDE, 0xE8,
+0x1B, 0x80, 0xDE, 0xE8,
+
+0x34, 0x80, 0x34, 0xBD,
+0x3C, 0x80, 0x3C, 0xBD,
+
+0x33, 0xD7, 0x0B, 0xBD,
+0x3B, 0xD7, 0x1B, 0xBD,
+
+0x48, 0x80, 0x48, 0xCF,
+0x59, 0x80, 0x59, 0xCF,
+
+0x68, 0x33, 0x68, 0xCF,
+0x49, 0x3B, 0x49, 0xCF,
+
+0xAD, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x58, 0x33, 0x58, 0xCF,
+0x69, 0x3B, 0x69, 0xCF,
+
+0x6B, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgz[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x58, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x4A, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x1D, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x2A, 0x44, 0x4C, 0xB4,
+0x1A, 0x44, 0x54, 0xB4,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0xAF, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xD6, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x9D, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgza[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x5C, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x4E, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x27, 0xCF, 0x74, 0xC6,
+0x3D, 0xCF, 0x74, 0xC2,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x20, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x27, 0x20, 0xE9,
+
+0x0A, 0x44, 0x4C, 0xB4,
+0x02, 0x44, 0x54, 0xB4,
+
+0x2A, 0x44, 0x4C, 0xB6,
+0x1A, 0x44, 0x54, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0xAB, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xD3, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x99, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzaf[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x61, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x53, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x34, 0x37, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x26, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x27, 0xCF, 0x74, 0xC6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x27, 0x20, 0xE9,
+
+0x0A, 0x44, 0x4C, 0xB4,
+0x02, 0x44, 0x54, 0xB4,
+
+0x2A, 0x44, 0x4C, 0xB6,
+0x1A, 0x44, 0x54, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x3D, 0xCF, 0x75, 0xC6,
+0x00, 0x80, 0x00, 0xE8,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x45, 0x4D, 0xB6,
+0x02, 0x45, 0x55, 0xB6,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x3D, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0xA6, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xCD, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x94, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzf[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x5D, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x4F, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x34, 0x80, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x27, 0xCF, 0x75, 0xC6,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x20, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x3D, 0xCF, 0x74, 0xC2,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x31, 0x27, 0x20, 0xE9,
+
+0x0A, 0x44, 0x4C, 0xB4,
+0x02, 0x44, 0x54, 0xB4,
+
+0x2A, 0x45, 0x4D, 0xB6,
+0x1A, 0x45, 0x55, 0xB6,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x38, 0x3D, 0x20, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0xAA, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xD3, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x98, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzs[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x65, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x57, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x27, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x29, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x27, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB4,
+0x1A, 0x44, 0x54, 0xB4,
+
+0x0A, 0x45, 0x4D, 0xB0,
+0x02, 0x45, 0x55, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x4D, 0xB2,
+0x1A, 0x45, 0x55, 0xB2,
+
+0x0A, 0x45, 0x4D, 0xB4,
+0x02, 0x45, 0x55, 0xB4,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x20,
+0x02, 0x20,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA7, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0xA2, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xCA, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x90, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzsa[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x6A, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x5C, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x27, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x2E, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x27, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB4,
+0x1A, 0x44, 0x54, 0xB4,
+
+0x0A, 0x45, 0x4D, 0xB0,
+0x02, 0x45, 0x55, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x4D, 0xB2,
+0x1A, 0x45, 0x55, 0xB2,
+
+0x0A, 0x45, 0x4D, 0xB4,
+0x02, 0x45, 0x55, 0xB4,
+
+0x27, 0xCF, 0x74, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB6,
+0x1A, 0x44, 0x54, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0x9D, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xC5, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x8B, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzsaf[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x6E, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x60, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x27, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x32, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x27, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB4,
+0x1A, 0x44, 0x54, 0xB4,
+
+0x0A, 0x45, 0x4D, 0xB0,
+0x02, 0x45, 0x55, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x4D, 0xB2,
+0x1A, 0x45, 0x55, 0xB2,
+
+0x0A, 0x45, 0x4D, 0xB4,
+0x02, 0x45, 0x55, 0xB4,
+
+0x27, 0xCF, 0x74, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9C, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB6,
+0x1A, 0x44, 0x54, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x45, 0x4D, 0xB6,
+0x02, 0x45, 0x55, 0xB6,
+
+0x3D, 0xCF, 0x75, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x31, 0x3D, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x9D, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x9E, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x30, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x38, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0x99, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xC1, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x87, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
+
+static unsigned char warp_g400_tgzsf[] = {
+
+0x00, 0x88, 0x98, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+0xFF, 0x80, 0xC0, 0xE9,
+0x00, 0x80, 0x00, 0xE8,
+
+0x22, 0x40, 0x48, 0xBF,
+0x2A, 0x40, 0x50, 0xBF,
+
+0x32, 0x41, 0x49, 0xBF,
+0x3A, 0x41, 0x51, 0xBF,
+
+0xC3, 0x6B,
+0xCB, 0x6B,
+0x00, 0x88, 0x98, 0xE9,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x96, 0xE2,
+0x41, 0x04,
+
+0x7B, 0x43, 0xA0, 0xE8,
+0x73, 0x4B, 0xA0, 0xE8,
+
+0xAD, 0xEE, 0x29, 0x9F,
+0x00, 0xE0,
+0x49, 0x04,
+
+0x90, 0xE2,
+0x51, 0x04,
+0x31, 0x46, 0xB1, 0xE8,
+
+0x49, 0x41, 0xC0, 0xEC,
+0x39, 0x57, 0xB1, 0xE8,
+
+0x00, 0x04,
+0x46, 0xE2,
+0x73, 0x53, 0xA0, 0xE8,
+
+0x51, 0x41, 0xC0, 0xEC,
+0x31, 0x00,
+0x39, 0x00,
+
+0x6A, 0x80, 0x15, 0xEA,
+0x08, 0x04,
+0x10, 0x04,
+
+0x51, 0x49, 0xC0, 0xEC,
+0x2F, 0x41, 0x60, 0xEA,
+
+0x31, 0x20,
+0x39, 0x20,
+0x1F, 0x42, 0xA0, 0xE8,
+
+0x2A, 0x42, 0x4A, 0xBF,
+0x27, 0x4A, 0xA0, 0xE8,
+
+0x1A, 0x42, 0x52, 0xBF,
+0x1E, 0x49, 0x60, 0xEA,
+
+0x73, 0x7B, 0xC8, 0xEC,
+0x26, 0x51, 0x60, 0xEA,
+
+0x32, 0x40, 0x48, 0xBD,
+0x22, 0x40, 0x50, 0xBD,
+
+0x12, 0x41, 0x49, 0xBD,
+0x3A, 0x41, 0x51, 0xBD,
+
+0xBF, 0x2F, 0x26, 0xBD,
+0x00, 0xE0,
+0x7B, 0x72,
+
+0x32, 0x20,
+0x22, 0x20,
+0x12, 0x20,
+0x3A, 0x20,
+
+0x46, 0x31, 0x46, 0xBF,
+0x4E, 0x31, 0x4E, 0xBF,
+
+0xB3, 0xE2, 0x2D, 0x9F,
+0x00, 0x80, 0x00, 0xE8,
+
+0x56, 0x31, 0x56, 0xBF,
+0x47, 0x39, 0x47, 0xBF,
+
+0x4F, 0x39, 0x4F, 0xBF,
+0x57, 0x39, 0x57, 0xBF,
+
+0x5C, 0x80, 0x07, 0xEA,
+0x24, 0x41, 0x20, 0xE9,
+
+0x42, 0x73, 0xF8, 0xEC,
+0x00, 0xE0,
+0x2D, 0x73,
+
+0x33, 0x72,
+0x0C, 0xE3,
+0xA5, 0x2F, 0x1E, 0xBD,
+
+0x43, 0x43, 0x2D, 0xDF,
+0x4B, 0x4B, 0x2D, 0xDF,
+
+0xAE, 0x1E, 0x26, 0xBD,
+0x58, 0xE3,
+0x33, 0x66,
+
+0x53, 0x53, 0x2D, 0xDF,
+0x00, 0x80, 0x00, 0xE8,
+
+0xB8, 0x38, 0x33, 0xBF,
+0x00, 0xE0,
+0x59, 0xE3,
+
+0x1E, 0x12, 0x41, 0xE9,
+0x1A, 0x22, 0x41, 0xE9,
+
+0x2B, 0x40, 0x3D, 0xE9,
+0x3F, 0x4B, 0xA0, 0xE8,
+
+0x2D, 0x73,
+0x30, 0x76,
+0x05, 0x80, 0x3D, 0xEA,
+
+0x37, 0x43, 0xA0, 0xE8,
+0x3D, 0x53, 0xA0, 0xE8,
+
+0x48, 0x70, 0xF8, 0xEC,
+0x2B, 0x48, 0x3C, 0xE9,
+
+0x1F, 0x27, 0xBC, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x00, 0x80, 0x00, 0xE8,
+0x00, 0x80, 0x00, 0xE8,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x15, 0xC0, 0x20, 0xE9,
+0x15, 0xC0, 0x20, 0xE9,
+
+0x18, 0x3A, 0x41, 0xE9,
+0x1D, 0x32, 0x41, 0xE9,
+
+0x2A, 0x40, 0x20, 0xE9,
+0x56, 0x3D, 0x56, 0xDF,
+
+0x46, 0x37, 0x46, 0xDF,
+0x4E, 0x3F, 0x4E, 0xDF,
+
+0x16, 0x30, 0x20, 0xE9,
+0x4F, 0x3F, 0x4F, 0xDF,
+
+0x47, 0x37, 0x47, 0xDF,
+0x57, 0x3D, 0x57, 0xDF,
+
+0x32, 0x32, 0x2D, 0xDF,
+0x22, 0x22, 0x2D, 0xDF,
+
+0x12, 0x12, 0x2D, 0xDF,
+0x3A, 0x3A, 0x2D, 0xDF,
+
+0x27, 0xCF, 0x74, 0xC2,
+0x37, 0xCF, 0x74, 0xC4,
+
+0x0A, 0x44, 0x4C, 0xB0,
+0x02, 0x44, 0x54, 0xB0,
+
+0x3D, 0xCF, 0x74, 0xC0,
+0x34, 0x37, 0x20, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x38, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3C, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB2,
+0x1A, 0x44, 0x54, 0xB2,
+
+0x2E, 0x80, 0x3A, 0xEA,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x27, 0xCF, 0x75, 0xC0,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x32, 0x31, 0x5F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x33, 0x39, 0x5F, 0xE9,
+
+0x3D, 0xCF, 0x75, 0xC2,
+0x37, 0xCF, 0x75, 0xC4,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA6, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA3, 0x3D, 0x20, 0xE9,
+
+0x2A, 0x44, 0x4C, 0xB4,
+0x1A, 0x44, 0x54, 0xB4,
+
+0x0A, 0x45, 0x4D, 0xB0,
+0x02, 0x45, 0x55, 0xB0,
+
+0x88, 0x73, 0x5E, 0xE9,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA0, 0x37, 0x20, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x3E, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x3F, 0x38, 0x4F, 0xE9,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x3A, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x3B, 0x39, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x4D, 0xB2,
+0x1A, 0x45, 0x55, 0xB2,
+
+0x0A, 0x45, 0x4D, 0xB4,
+0x02, 0x45, 0x55, 0xB4,
+
+0x27, 0xCF, 0x75, 0xC6,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0xA7, 0x30, 0x4F, 0xE9,
+0x0A, 0x20,
+0x02, 0x20,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x31, 0x27, 0x20, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA8, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x45, 0x4D, 0xB6,
+0x1A, 0x45, 0x55, 0xB6,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x36, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x37, 0x39, 0x4F, 0xE9,
+
+0x00, 0x80, 0x00, 0xE8,
+0x2A, 0x20,
+0x1A, 0x20,
+
+0x2A, 0x46, 0x4E, 0xBF,
+0x1A, 0x46, 0x56, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA4, 0x31, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA5, 0x39, 0x4F, 0xE9,
+
+0x0A, 0x47, 0x4F, 0xBF,
+0x02, 0x47, 0x57, 0xBF,
+
+0x31, 0x53, 0x2F, 0x9F,
+0xA1, 0x30, 0x4F, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0xA2, 0x38, 0x4F, 0xE9,
+
+0x2A, 0x43, 0x4B, 0xBF,
+0x1A, 0x43, 0x53, 0xBF,
+
+0x30, 0x50, 0x2E, 0x9F,
+0x35, 0x31, 0x4F, 0xE9,
+
+0x38, 0x21, 0x2C, 0x9F,
+0x39, 0x39, 0x4F, 0xE9,
+
+0x31, 0x53, 0x2F, 0x9F,
+0x80, 0x31, 0x57, 0xE9,
+
+0x39, 0xE5, 0x2C, 0x9F,
+0x81, 0x39, 0x57, 0xE9,
+
+0x37, 0x48, 0x50, 0xBD,
+0x8A, 0x36, 0x20, 0xE9,
+
+0x86, 0x76, 0x57, 0xE9,
+0x8B, 0x3E, 0x20, 0xE9,
+
+0x82, 0x30, 0x57, 0xE9,
+0x87, 0x77, 0x57, 0xE9,
+
+0x83, 0x38, 0x57, 0xE9,
+0x35, 0x49, 0x51, 0xBD,
+
+0x84, 0x31, 0x5E, 0xE9,
+0x30, 0x1F, 0x5F, 0xE9,
+
+0x85, 0x39, 0x5E, 0xE9,
+0x57, 0x25, 0x20, 0xE9,
+
+0x2B, 0x48, 0x20, 0xE9,
+0x1D, 0x37, 0xE1, 0xEA,
+
+0x1E, 0x35, 0xE1, 0xEA,
+0x00, 0xE0,
+0x26, 0x77,
+
+0x24, 0x49, 0x20, 0xE9,
+0x9D, 0xFF, 0x20, 0xEA,
+
+0x16, 0x26, 0x20, 0xE9,
+0x57, 0x2E, 0xBF, 0xEA,
+
+0x1C, 0x46, 0xA0, 0xE8,
+0x23, 0x4E, 0xA0, 0xE8,
+
+0x2B, 0x56, 0xA0, 0xE8,
+0x1D, 0x47, 0xA0, 0xE8,
+
+0x24, 0x4F, 0xA0, 0xE8,
+0x2C, 0x57, 0xA0, 0xE8,
+
+0x1C, 0x00,
+0x23, 0x00,
+0x2B, 0x00,
+0x00, 0xE0,
+
+0x1D, 0x00,
+0x24, 0x00,
+0x2C, 0x00,
+0x00, 0xE0,
+
+0x1C, 0x65,
+0x23, 0x65,
+0x2B, 0x65,
+0x00, 0xE0,
+
+0x1D, 0x65,
+0x24, 0x65,
+0x2C, 0x65,
+0x00, 0xE0,
+
+0x1C, 0x23, 0x60, 0xEC,
+0x36, 0xD7, 0x36, 0xAD,
+
+0x2B, 0x80, 0x60, 0xEC,
+0x1D, 0x24, 0x60, 0xEC,
+
+0x3E, 0xD7, 0x3E, 0xAD,
+0x2C, 0x80, 0x60, 0xEC,
+
+0x1C, 0x2B, 0xDE, 0xE8,
+0x23, 0x80, 0xDE, 0xE8,
+
+0x36, 0x80, 0x36, 0xBD,
+0x3E, 0x80, 0x3E, 0xBD,
+
+0x33, 0xD7, 0x1C, 0xBD,
+0x3B, 0xD7, 0x23, 0xBD,
+
+0x46, 0x80, 0x46, 0xCF,
+0x4F, 0x80, 0x4F, 0xCF,
+
+0x56, 0x33, 0x56, 0xCF,
+0x47, 0x3B, 0x47, 0xCF,
+
+0xC5, 0xFF, 0x20, 0xEA,
+0x00, 0x80, 0x00, 0xE8,
+
+0x4E, 0x33, 0x4E, 0xCF,
+0x57, 0x3B, 0x57, 0xCF,
+
+0x8B, 0xFF, 0x20, 0xEA,
+0x57, 0xC0, 0xBF, 0xEA,
+
+0x00, 0x80, 0xA0, 0xE9,
+0x00, 0x00, 0xD8, 0xEC,
+
+};
diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
new file mode 100644 (file)
index 0000000..fba691b
--- /dev/null
@@ -0,0 +1,210 @@
+/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*-
+ * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#define __NO_VERSION__
+#include "mga.h"
+#include "drmP.h"
+#include "mga_drv.h"
+#include "mga_ucode.h"
+
+
+#define MGA_WARP_CODE_ALIGN            256             /* in bytes */
+
+#define WARP_UCODE_SIZE( which )                                       \
+       ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
+
+#define WARP_UCODE_INSTALL( which, where )                             \
+do {                                                                   \
+       DRM_DEBUG( " pcbase = 0x%08lx  vcbase = %p\n", pcbase, vcbase );\
+       dev_priv->warp_pipe_phys[where] = pcbase;                       \
+       memcpy( vcbase, which, sizeof(which) );                         \
+       pcbase += WARP_UCODE_SIZE( which );                             \
+       vcbase += WARP_UCODE_SIZE( which );                             \
+} while (0)
+
+
+static unsigned int mga_warp_g400_microcode_size( drm_mga_private_t *dev_priv )
+{
+       unsigned int size;
+
+       size = ( WARP_UCODE_SIZE( warp_g400_tgz ) +
+                WARP_UCODE_SIZE( warp_g400_tgza ) +
+                WARP_UCODE_SIZE( warp_g400_tgzaf ) +
+                WARP_UCODE_SIZE( warp_g400_tgzf ) +
+                WARP_UCODE_SIZE( warp_g400_tgzs ) +
+                WARP_UCODE_SIZE( warp_g400_tgzsa ) +
+                WARP_UCODE_SIZE( warp_g400_tgzsaf ) +
+                WARP_UCODE_SIZE( warp_g400_tgzsf ) +
+                WARP_UCODE_SIZE( warp_g400_t2gz ) +
+                WARP_UCODE_SIZE( warp_g400_t2gza ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzaf ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzf ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzs ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzsa ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzsaf ) +
+                WARP_UCODE_SIZE( warp_g400_t2gzsf ) );
+
+       size = PAGE_ALIGN( size );
+
+       DRM_DEBUG( "G400 ucode size = %d bytes\n", size );
+       return size;
+}
+
+static unsigned int mga_warp_g200_microcode_size( drm_mga_private_t *dev_priv )
+{
+       unsigned int size;
+
+       size = ( WARP_UCODE_SIZE( warp_g200_tgz ) +
+                WARP_UCODE_SIZE( warp_g200_tgza ) +
+                WARP_UCODE_SIZE( warp_g200_tgzaf ) +
+                WARP_UCODE_SIZE( warp_g200_tgzf ) +
+                WARP_UCODE_SIZE( warp_g200_tgzs ) +
+                WARP_UCODE_SIZE( warp_g200_tgzsa ) +
+                WARP_UCODE_SIZE( warp_g200_tgzsaf ) +
+                WARP_UCODE_SIZE( warp_g200_tgzsf ) );
+
+       size = PAGE_ALIGN( size );
+
+       DRM_DEBUG( "G200 ucode size = %d bytes\n", size );
+       return size;
+}
+
+static int mga_warp_install_g400_microcode( drm_mga_private_t *dev_priv )
+{
+       unsigned char *vcbase = dev_priv->warp->handle;
+       unsigned long pcbase = dev_priv->warp->offset;
+       unsigned int size;
+
+       size = mga_warp_g400_microcode_size( dev_priv );
+       if ( size > dev_priv->warp->size ) {
+               DRM_ERROR( "microcode too large! (%u > %lu)\n",
+                          size, dev_priv->warp->size );
+               return -ENOMEM;
+       }
+
+       memset( dev_priv->warp_pipe_phys, 0,
+               sizeof(dev_priv->warp_pipe_phys) );
+
+       WARP_UCODE_INSTALL( warp_g400_tgz,      MGA_WARP_TGZ );
+       WARP_UCODE_INSTALL( warp_g400_tgzf,     MGA_WARP_TGZF );
+       WARP_UCODE_INSTALL( warp_g400_tgza,     MGA_WARP_TGZA );
+       WARP_UCODE_INSTALL( warp_g400_tgzaf,    MGA_WARP_TGZAF );
+       WARP_UCODE_INSTALL( warp_g400_tgzs,     MGA_WARP_TGZS );
+       WARP_UCODE_INSTALL( warp_g400_tgzsf,    MGA_WARP_TGZSF );
+       WARP_UCODE_INSTALL( warp_g400_tgzsa,    MGA_WARP_TGZSA );
+       WARP_UCODE_INSTALL( warp_g400_tgzsaf,   MGA_WARP_TGZSAF );
+
+       WARP_UCODE_INSTALL( warp_g400_t2gz,     MGA_WARP_T2GZ );
+       WARP_UCODE_INSTALL( warp_g400_t2gzf,    MGA_WARP_T2GZF );
+       WARP_UCODE_INSTALL( warp_g400_t2gza,    MGA_WARP_T2GZA );
+       WARP_UCODE_INSTALL( warp_g400_t2gzaf,   MGA_WARP_T2GZAF );
+       WARP_UCODE_INSTALL( warp_g400_t2gzs,    MGA_WARP_T2GZS );
+       WARP_UCODE_INSTALL( warp_g400_t2gzsf,   MGA_WARP_T2GZSF );
+       WARP_UCODE_INSTALL( warp_g400_t2gzsa,   MGA_WARP_T2GZSA );
+       WARP_UCODE_INSTALL( warp_g400_t2gzsaf,  MGA_WARP_T2GZSAF );
+
+       return 0;
+}
+
+static int mga_warp_install_g200_microcode( drm_mga_private_t *dev_priv )
+{
+       unsigned char *vcbase = dev_priv->warp->handle;
+       unsigned long pcbase = dev_priv->warp->offset;
+       unsigned int size;
+
+       size = mga_warp_g200_microcode_size( dev_priv );
+       if ( size > dev_priv->warp->size ) {
+               DRM_ERROR( "microcode too large! (%u > %lu)\n",
+                          size, dev_priv->warp->size );
+               return -ENOMEM;
+       }
+
+       memset( dev_priv->warp_pipe_phys, 0,
+               sizeof(dev_priv->warp_pipe_phys) );
+
+       WARP_UCODE_INSTALL( warp_g200_tgz,      MGA_WARP_TGZ );
+       WARP_UCODE_INSTALL( warp_g200_tgzf,     MGA_WARP_TGZF );
+       WARP_UCODE_INSTALL( warp_g200_tgza,     MGA_WARP_TGZA );
+       WARP_UCODE_INSTALL( warp_g200_tgzaf,    MGA_WARP_TGZAF );
+       WARP_UCODE_INSTALL( warp_g200_tgzs,     MGA_WARP_TGZS );
+       WARP_UCODE_INSTALL( warp_g200_tgzsf,    MGA_WARP_TGZSF );
+       WARP_UCODE_INSTALL( warp_g200_tgzsa,    MGA_WARP_TGZSA );
+       WARP_UCODE_INSTALL( warp_g200_tgzsaf,   MGA_WARP_TGZSAF );
+
+       return 0;
+}
+
+int mga_warp_install_microcode(        drm_mga_private_t *dev_priv )
+{
+       switch ( dev_priv->chipset ) {
+       case MGA_CARD_TYPE_G400:
+               return mga_warp_install_g400_microcode( dev_priv );
+       case MGA_CARD_TYPE_G200:
+               return mga_warp_install_g200_microcode( dev_priv );
+       default:
+               return -EINVAL;
+       }
+}
+
+#define WMISC_EXPECTED         (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
+
+int mga_warp_init( drm_mga_private_t *dev_priv )
+{
+       u32 wmisc;
+
+       /* FIXME: Get rid of these damned magic numbers...
+        */
+       switch ( dev_priv->chipset ) {
+       case MGA_CARD_TYPE_G400:
+               MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND );
+               MGA_WRITE( MGA_WGETMSB, 0x00000E00 );
+               MGA_WRITE( MGA_WVRTXSZ, 0x00001807 );
+               MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 );
+               break;
+       case MGA_CARD_TYPE_G200:
+               MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
+               MGA_WRITE( MGA_WGETMSB, 0x1606 );
+               MGA_WRITE( MGA_WVRTXSZ, 7 );
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
+                              MGA_WMASTER_ENABLE |
+                              MGA_WCACHEFLUSH_ENABLE) );
+       wmisc = MGA_READ( MGA_WMISC );
+       if ( wmisc != WMISC_EXPECTED ) {
+               DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
+                          wmisc, WMISC_EXPECTED );
+               return -EINVAL;
+       }
+
+       return 0;
+}
diff --git a/drivers/char/drm/proc.c b/drivers/char/drm/proc.c
deleted file mode 100644 (file)
index ea2d376..0000000
+++ /dev/null
@@ -1,578 +0,0 @@
-/* proc.c -- /proc support for DRM -*- linux-c -*-
- * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-static struct proc_dir_entry *drm_root    = NULL;
-static struct proc_dir_entry *drm_dev_root = NULL;
-static char                 drm_slot_name[64];
-
-static int        drm_name_info(char *buf, char **start, off_t offset,
-                                int len, int *eof, void *data);
-static int        drm_vm_info(char *buf, char **start, off_t offset,
-                              int len, int *eof, void *data);
-static int        drm_clients_info(char *buf, char **start, off_t offset,
-                                   int len, int *eof, void *data);
-static int        drm_queues_info(char *buf, char **start, off_t offset,
-                                  int len, int *eof, void *data);
-static int        drm_bufs_info(char *buf, char **start, off_t offset,
-                                int len, int *eof, void *data);
-#if DRM_DEBUG_CODE
-static int        drm_vma_info(char *buf, char **start, off_t offset,
-                               int len, int *eof, void *data);
-#endif
-#if DRM_DMA_HISTOGRAM
-static int        drm_histo_info(char *buf, char **start, off_t offset,
-                                 int len, int *eof, void *data);
-#endif
-
-struct drm_proc_list {
-       const char *name;
-       int        (*f)(char *, char **, off_t, int, int *, void *);
-} drm_proc_list[] = {
-       { "name",    drm_name_info    },
-       { "mem",     drm_mem_info     },
-       { "vm",      drm_vm_info      },
-       { "clients", drm_clients_info },
-       { "queues",  drm_queues_info  },
-       { "bufs",    drm_bufs_info    },
-#if DRM_DEBUG_CODE
-       { "vma",     drm_vma_info     },
-#endif
-#if DRM_DMA_HISTOGRAM
-       { "histo",   drm_histo_info   },
-#endif
-};
-#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
-
-int drm_proc_init(drm_device_t *dev)
-{
-       struct proc_dir_entry *ent;
-       int                   i, j;
-
-       drm_root = create_proc_entry("dri", S_IFDIR, NULL);
-       if (!drm_root) {
-               DRM_ERROR("Cannot create /proc/dri\n");
-               return -1;
-       }
-
-                               /* Instead of doing this search, we should
-                                  add some global support for /proc/dri. */
-       for (i = 0; i < 8; i++) {
-               sprintf(drm_slot_name, "dri/%d", i);
-               drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
-               if (!drm_dev_root) {
-                       DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
-                       remove_proc_entry("dri", NULL);
-                       break;
-               }
-               if (drm_dev_root->nlink == 2) break;
-               drm_dev_root = NULL;
-       }
-       if (!drm_dev_root) {
-               DRM_ERROR("Cannot find slot in /proc/dri\n");
-               return -1;
-       }
-
-       for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-               ent = create_proc_entry(drm_proc_list[i].name,
-                                       S_IFREG|S_IRUGO, drm_dev_root);
-               if (!ent) {
-                       DRM_ERROR("Cannot create /proc/%s/%s\n",
-                                 drm_slot_name, drm_proc_list[i].name);
-                       for (j = 0; j < i; j++)
-                               remove_proc_entry(drm_proc_list[i].name,
-                                                 drm_dev_root);
-                       remove_proc_entry(drm_slot_name, NULL);
-                       remove_proc_entry("dri", NULL);
-                       return -1;
-               }
-               ent->read_proc = drm_proc_list[i].f;
-               ent->data      = dev;
-       }
-
-       return 0;
-}
-
-
-int drm_proc_cleanup(void)
-{
-       int i;
-       
-       if (drm_root) {
-               if (drm_dev_root) {
-                       for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-                               remove_proc_entry(drm_proc_list[i].name,
-                                                 drm_dev_root);
-                       }
-                       remove_proc_entry(drm_slot_name, NULL);
-               }
-               remove_proc_entry("dri", NULL);
-               remove_proc_entry(DRM_NAME, NULL);
-       }
-       drm_root = drm_dev_root = NULL;
-       return 0;
-}
-
-static int drm_name_info(char *buf, char **start, off_t offset, int len,
-                        int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-
-       if (dev->unique) {
-               DRM_PROC_PRINT("%s 0x%x %s\n",
-                              dev->name, dev->device, dev->unique);
-       } else {
-               DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
-       }
-       return len;
-}
-
-static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
-                       int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       drm_map_t    *map;
-                               /* Hardcoded from _DRM_FRAME_BUFFER,
-                                   _DRM_REGISTERS, _DRM_SHM, and
-                                   _DRM_AGP. */
-       const char   *types[] = { "FB", "REG", "SHM", "AGP" };
-       const char   *type;
-       int          i;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT("slot     offset       size type flags    "
-                      "address mtrr\n\n");
-       for (i = 0; i < dev->map_count; i++) {
-               map = dev->maplist[i];
-               if (map->type < 0 || map->type > 3) type = "??";
-               else                                type = types[map->type];
-               DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
-                              i,
-                              map->offset,
-                              map->size,
-                              type,
-                              map->flags,
-                              (unsigned long)map->handle);
-               if (map->mtrr < 0) {
-                       DRM_PROC_PRINT("none\n");
-               } else {
-                       DRM_PROC_PRINT("%4d\n", map->mtrr);
-               }
-       }
-
-       return len;
-}
-
-static int drm_vm_info(char *buf, char **start, off_t offset, int len,
-                      int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_vm_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-
-
-static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
-                           int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          i;
-       drm_queue_t  *q;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT("  ctx/flags   use   fin"
-                      "   blk/rw/rwf  wait    flushed     queued"
-                      "      locks\n\n");
-       for (i = 0; i < dev->queue_count; i++) {
-               q = dev->queuelist[i];
-               atomic_inc(&q->use_count);
-               DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
-                                  "%5d/0x%03x %5d %5d"
-                                  " %5d/%c%c/%c%c%c %5Zd %10d %10d %10d\n",
-                                  i,
-                                  q->flags,
-                                  atomic_read(&q->use_count),
-                                  atomic_read(&q->finalization),
-                                  atomic_read(&q->block_count),
-                                  atomic_read(&q->block_read) ? 'r' : '-',
-                                  atomic_read(&q->block_write) ? 'w' : '-',
-                                  waitqueue_active(&q->read_queue) ? 'r':'-',
-                                  waitqueue_active(&q->write_queue) ? 'w':'-',
-                                  waitqueue_active(&q->flush_queue) ? 'f':'-',
-                                  DRM_BUFCOUNT(&q->waitlist),
-                                  atomic_read(&q->total_flushed),
-                                  atomic_read(&q->total_queued),
-                                  atomic_read(&q->total_locks));
-               atomic_dec(&q->use_count);
-       }
-       
-       return len;
-}
-
-static int drm_queues_info(char *buf, char **start, off_t offset, int len,
-                          int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_queues_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-
-/* drm_bufs_info is called whenever a process reads
-   /dev/drm/<dev>/bufs. */
-
-static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
-                         int *eof, void *data)
-{
-       drm_device_t     *dev = (drm_device_t *)data;
-       drm_device_dma_t *dma = dev->dma;
-       int              i;
-
-       if (!dma)       return 0;
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT(" o     size count  free  segs pages    kB\n\n");
-       for (i = 0; i <= DRM_MAX_ORDER; i++) {
-               if (dma->bufs[i].buf_count)
-                       DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
-                                      i,
-                                      dma->bufs[i].buf_size,
-                                      dma->bufs[i].buf_count,
-                                      atomic_read(&dma->bufs[i]
-                                                  .freelist.count),
-                                      dma->bufs[i].seg_count,
-                                      dma->bufs[i].seg_count
-                                      *(1 << dma->bufs[i].page_order),
-                                      (dma->bufs[i].seg_count
-                                       * (1 << dma->bufs[i].page_order))
-                                      * PAGE_SIZE / 1024);
-       }
-       DRM_PROC_PRINT("\n");
-       for (i = 0; i < dma->buf_count; i++) {
-               if (i && !(i%32)) DRM_PROC_PRINT("\n");
-               DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
-       }
-       DRM_PROC_PRINT("\n");
-
-       return len;
-}
-
-static int drm_bufs_info(char *buf, char **start, off_t offset, int len,
-                        int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_bufs_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-
-
-static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
-                            int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       drm_file_t   *priv;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT("a dev   pid    uid      magic     ioctls\n\n");
-       for (priv = dev->file_first; priv; priv = priv->next) {
-               DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
-                              priv->authenticated ? 'y' : 'n',
-                              priv->minor,
-                              priv->pid,
-                              priv->uid,
-                              priv->magic,
-                              priv->ioctl_count);
-       }
-
-       return len;
-}
-
-static int drm_clients_info(char *buf, char **start, off_t offset, int len,
-                           int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_clients_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-
-#if DRM_DEBUG_CODE
-
-#define DRM_VMA_VERBOSE 0
-
-static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
-                        int *eof, void *data)
-{
-       drm_device_t          *dev = (drm_device_t *)data;
-       drm_vma_entry_t       *pt;
-       struct vm_area_struct *vma;
-#if DRM_VMA_VERBOSE
-       unsigned long         i;
-       unsigned long         address;
-       pgd_t                 *pgd;
-       pmd_t                 *pmd;
-       pte_t                 *pte;
-#endif
-#if defined(__i386__)
-       unsigned int          pgprot;
-#endif
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-       DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
-                      atomic_read(&dev->vma_count),
-                      high_memory, virt_to_phys(high_memory));
-       for (pt = dev->vmalist; pt; pt = pt->next) {
-               if (!(vma = pt->vma)) continue;
-               DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
-                              pt->pid,
-                              vma->vm_start,
-                              vma->vm_end,
-                              vma->vm_flags & VM_READ     ? 'r' : '-',
-                              vma->vm_flags & VM_WRITE    ? 'w' : '-',
-                              vma->vm_flags & VM_EXEC     ? 'x' : '-',
-                              vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
-                              vma->vm_flags & VM_LOCKED   ? 'l' : '-',
-                              vma->vm_flags & VM_IO       ? 'i' : '-',
-                              VM_OFFSET(vma));
-               
-#if defined(__i386__)
-               pgprot = pgprot_val(vma->vm_page_prot);
-               DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
-                              pgprot & _PAGE_PRESENT  ? 'p' : '-',
-                              pgprot & _PAGE_RW       ? 'w' : 'r',
-                              pgprot & _PAGE_USER     ? 'u' : 's',
-                              pgprot & _PAGE_PWT      ? 't' : 'b',
-                              pgprot & _PAGE_PCD      ? 'u' : 'c',
-                              pgprot & _PAGE_ACCESSED ? 'a' : '-',
-                              pgprot & _PAGE_DIRTY    ? 'd' : '-',
-                              pgprot & _PAGE_PSE      ? 'm' : 'k',
-                              pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
-#endif         
-               DRM_PROC_PRINT("\n");
-#if 0
-               for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
-                       pgd = pgd_offset(vma->vm_mm, i);
-                       pmd = pmd_offset(pgd, i);
-                       pte = pte_offset(pmd, i);
-                       if (pte_present(*pte)) {
-                               address = __pa(pte_page(*pte))
-                                       + (i & (PAGE_SIZE-1));
-                               DRM_PROC_PRINT("      0x%08lx -> 0x%08lx"
-                                              " %c%c%c%c%c\n",
-                                              i,
-                                              address,
-                                              pte_read(*pte)  ? 'r' : '-',
-                                              pte_write(*pte) ? 'w' : '-',
-                                              pte_exec(*pte)  ? 'x' : '-',
-                                              pte_dirty(*pte) ? 'd' : '-',
-                                              pte_young(*pte) ? 'a' : '-' );
-                       } else {
-                               DRM_PROC_PRINT("      0x%08lx\n", i);
-                       }
-               }
-#endif
-       }
-       
-       return len;
-}
-
-static int drm_vma_info(char *buf, char **start, off_t offset, int len,
-                       int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_vma_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-#endif
-
-
-#if DRM_DMA_HISTOGRAM
-static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
-                          int *eof, void *data)
-{
-       drm_device_t     *dev = (drm_device_t *)data;
-       drm_device_dma_t *dma = dev->dma;
-       int              i;
-       unsigned long    slot_value = DRM_DMA_HISTOGRAM_INITIAL;
-       unsigned long    prev_value = 0;
-       drm_buf_t        *buffer;
-
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
-
-       DRM_PROC_PRINT("general statistics:\n");
-       DRM_PROC_PRINT("total    %10u\n", atomic_read(&dev->histo.total));
-       DRM_PROC_PRINT("open     %10u\n", atomic_read(&dev->total_open));
-       DRM_PROC_PRINT("close    %10u\n", atomic_read(&dev->total_close));
-       DRM_PROC_PRINT("ioctl    %10u\n", atomic_read(&dev->total_ioctl));
-       DRM_PROC_PRINT("irq      %10u\n", atomic_read(&dev->total_irq));
-       DRM_PROC_PRINT("ctx      %10u\n", atomic_read(&dev->total_ctx));
-       
-       DRM_PROC_PRINT("\nlock statistics:\n");
-       DRM_PROC_PRINT("locks    %10u\n", atomic_read(&dev->total_locks));
-       DRM_PROC_PRINT("unlocks  %10u\n", atomic_read(&dev->total_unlocks));
-       DRM_PROC_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
-       DRM_PROC_PRINT("sleeps   %10u\n", atomic_read(&dev->total_sleeps));
-
-
-       if (dma) {
-               DRM_PROC_PRINT("\ndma statistics:\n");
-               DRM_PROC_PRINT("prio     %10u\n",
-                              atomic_read(&dma->total_prio));
-               DRM_PROC_PRINT("bytes    %10u\n",
-                              atomic_read(&dma->total_bytes));
-               DRM_PROC_PRINT("dmas     %10u\n",
-                              atomic_read(&dma->total_dmas));
-               DRM_PROC_PRINT("missed:\n");
-               DRM_PROC_PRINT("  dma    %10u\n",
-                              atomic_read(&dma->total_missed_dma));
-               DRM_PROC_PRINT("  lock   %10u\n",
-                              atomic_read(&dma->total_missed_lock));
-               DRM_PROC_PRINT("  free   %10u\n",
-                              atomic_read(&dma->total_missed_free));
-               DRM_PROC_PRINT("  sched  %10u\n",
-                              atomic_read(&dma->total_missed_sched));
-               DRM_PROC_PRINT("tried    %10u\n",
-                              atomic_read(&dma->total_tried));
-               DRM_PROC_PRINT("hit      %10u\n",
-                              atomic_read(&dma->total_hit));
-               DRM_PROC_PRINT("lost     %10u\n",
-                              atomic_read(&dma->total_lost));
-               
-               buffer = dma->next_buffer;
-               if (buffer) {
-                       DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx);
-               } else {
-                       DRM_PROC_PRINT("next_buffer    none\n");
-               }
-               buffer = dma->this_buffer;
-               if (buffer) {
-                       DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx);
-               } else {
-                       DRM_PROC_PRINT("this_buffer    none\n");
-               }
-       }
-       
-
-       DRM_PROC_PRINT("\nvalues:\n");
-       if (dev->lock.hw_lock) {
-               DRM_PROC_PRINT("lock           0x%08x\n",
-                              dev->lock.hw_lock->lock);
-       } else {
-               DRM_PROC_PRINT("lock                 none\n");
-       }
-       DRM_PROC_PRINT("context_flag   0x%08lx\n", dev->context_flag);
-       DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
-       DRM_PROC_PRINT("dma_flag       0x%08lx\n", dev->dma_flag);
-
-       DRM_PROC_PRINT("queue_count    %10d\n",  dev->queue_count);
-       DRM_PROC_PRINT("last_context   %10d\n",  dev->last_context);
-       DRM_PROC_PRINT("last_switch    %10lu\n", dev->last_switch);
-       DRM_PROC_PRINT("last_checked   %10d\n",  dev->last_checked);
-               
-       
-       DRM_PROC_PRINT("\n                     q2d        d2c        c2f"
-                      "        q2c        q2f        dma        sch"
-                      "        ctx       lacq       lhld\n\n");
-       for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
-               DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
-                              " %10u %10u %10u %10u %10u\n",
-                              i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
-                              i == DRM_DMA_HISTOGRAM_SLOTS - 1
-                              ? prev_value : slot_value ,
-                              
-                              atomic_read(&dev->histo
-                                          .queued_to_dispatched[i]),
-                              atomic_read(&dev->histo
-                                          .dispatched_to_completed[i]),
-                              atomic_read(&dev->histo
-                                          .completed_to_freed[i]),
-                              
-                              atomic_read(&dev->histo
-                                          .queued_to_completed[i]),
-                              atomic_read(&dev->histo
-                                          .queued_to_freed[i]),
-                              atomic_read(&dev->histo.dma[i]),
-                              atomic_read(&dev->histo.schedule[i]),
-                              atomic_read(&dev->histo.ctx[i]),
-                              atomic_read(&dev->histo.lacq[i]),
-                              atomic_read(&dev->histo.lhld[i]));
-               prev_value = slot_value;
-               slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
-       }
-       return len;
-}
-
-static int drm_histo_info(char *buf, char **start, off_t offset, int len,
-                         int *eof, void *data)
-{
-       drm_device_t *dev = (drm_device_t *)data;
-       int          ret;
-
-       down(&dev->struct_sem);
-       ret = _drm_histo_info(buf, start, offset, len, eof, data);
-       up(&dev->struct_sem);
-       return ret;
-}
-#endif
diff --git a/drivers/char/drm/r128.h b/drivers/char/drm/r128.h
new file mode 100644 (file)
index 0000000..926b4bf
--- /dev/null
@@ -0,0 +1,81 @@
+/* r128.h -- ATI Rage 128 DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 16:07:10 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __R128_H__
+#define __R128_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) r128_##x
+
+/* General customization:
+ */
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                0
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+#define __HAVE_SG              1
+#define __HAVE_PCI_DMA         1
+
+/* Driver customization:
+ */
+#define DRIVER_PRERELEASE() do {                                       \
+       if ( dev->dev_private ) {                                       \
+               drm_r128_private_t *dev_priv = dev->dev_private;        \
+               if ( dev_priv->page_flipping ) {                        \
+                       r128_do_cleanup_pageflip( dev );                \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) r128_do_cleanup_cce( dev );             \
+} while (0)
+
+/* DMA customization:
+ */
+#define __HAVE_DMA             1
+
+#if 0
+/* GH: Remove this for now... */
+#define __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       drm_r128_private_t *dev_priv = dev->dev_private;                \
+       return r128_do_cce_idle( dev_priv );                            \
+} while (0)
+#endif
+
+/* Buffer customization:
+ */
+#define DRIVER_BUF_PRIV_T      drm_r128_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_r128_private_t *)((dev)->dev_private))->buffers
+
+#endif
diff --git a/drivers/char/drm/r128_bufs.c b/drivers/char/drm/r128_bufs.c
deleted file mode 100644 (file)
index 319c339..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/* r128_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
- * Created: Wed Apr 12 16:19:08 2000 by kevin@precisioninsight.com
- *
- * Copyright 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
- * 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: Kevin E. Martin <martin@valinux.com>
- *          Rickard E. (Rik) Faith <faith@valinux.com>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include <linux/config.h>
-#include "drmP.h"
-#include "r128_drv.h"
-#include "linux/un.h"
-
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
-                    unsigned long arg)
-{
-       drm_file_t       *priv = filp->private_data;
-       drm_device_t     *dev  = priv->dev;
-       drm_device_dma_t *dma  = dev->dma;
-       drm_buf_desc_t    request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       count      = request.count;
-       order      = drm_order(request.size);
-       size       = 1 << order;
-
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(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: %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 -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-
-       /* Might be a poor limit, but take that up with XFree86 
-          if its a problem */
-          
-       if(count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -EINVAL;
-       }
-               
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM;
-       }
-       memset(entry->buflist, 0, count * sizeof(*entry->buflist));
-
-       entry->buf_size   = size;
-       entry->page_order = page_order;
-       offset            = 0;
-
-       for (offset = 0;
-            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 + offset);
-               buf->address = (void *)(agp_offset + offset);
-               buf->next    = NULL;
-               buf->waiting = 0;
-               buf->pending = 0;
-               init_waitqueue_head(&buf->dma_wait);
-               buf->pid     = 0;
-
-               buf->dev_priv_size = sizeof(drm_r128_buf_priv_t);
-               buf->dev_private   = drm_alloc(sizeof(drm_r128_buf_priv_t),
-                                              DRM_MEM_BUFS);
-               memset(buf->dev_private, 0, buf->dev_priv_size);
-
-#if DRM_DMA_HISTOGRAM
-               buf->time_queued     = 0;
-               buf->time_dispatched = 0;
-               buf->time_completed  = 0;
-               buf->time_freed      = 0;
-#endif
-
-               byte_count += PAGE_SIZE << page_order;
-
-               DRM_DEBUG("buffer %d @ %p\n",
-                         entry->buf_count, buf->address);
-       }
-
-       DRM_DEBUG("byte_count: %d\n", byte_count);
-
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
-       dma->buf_count  += entry->buf_count;
-       dma->byte_count += byte_count;
-
-       drm_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-
-       up(&dev->struct_sem);
-
-       request.count = entry->buf_count;
-       request.size  = size;
-
-       if (copy_to_user((drm_buf_desc_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-
-       dma->flags = _DRM_DMA_USE_AGP;
-
-       atomic_dec(&dev->buf_alloc);
-       return 0;
-}
-#endif
-
-int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t              *priv           = filp->private_data;
-       drm_device_t            *dev            = priv->dev;
-       drm_r128_private_t      *dev_priv       = dev->dev_private;
-       drm_buf_desc_t          request;
-
-       if (!dev_priv || dev_priv->is_pci) return -EINVAL;
-
-       if (copy_from_user(&request,
-                          (drm_buf_desc_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       if (request.flags & _DRM_AGP_BUFFER)
-               return r128_addbufs_agp(inode, filp, cmd, arg);
-       else
-#endif
-               return -EINVAL;
-}
-
-int r128_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t              *priv           = filp->private_data;
-       drm_device_t            *dev            = priv->dev;
-       drm_r128_private_t      *dev_priv       = dev->dev_private;
-       drm_device_dma_t        *dma            = dev->dma;
-       int                      retcode        = 0;
-       const int                zero           = 0;
-       unsigned long            virtual;
-       unsigned long            address;
-       drm_buf_map_t            request;
-       int                      i;
-
-       if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL;
-
-       DRM_DEBUG("\n");
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request,
-                          (drm_buf_map_t *)arg,
-                          sizeof(request)))
-               return -EFAULT;
-
-       if (request.count >= dma->buf_count) {
-               if (dma->flags & _DRM_DMA_USE_AGP) {
-                       drm_map_t *map;
-
-                       map = dev_priv->buffers;
-                       if (!map) {
-                               retcode = -EINVAL;
-                               goto done;
-                       }
-
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size,
-                                         PROT_READ|PROT_WRITE,
-                                         MAP_SHARED,
-                                         (unsigned long)map->offset);
-                       up_write(&current->mm->mmap_sem);
-               } else {
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
-                                         PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-                       up_write(&current->mm->mmap_sem);
-               }
-               if (virtual > -1024UL) {
-                       /* Real error */
-                       retcode = (signed long)virtual;
-                       goto done;
-               }
-               request.virtual = (void *)virtual;
-
-               for (i = 0; i < dma->buf_count; i++) {
-                       if (copy_to_user(&request.list[i].idx,
-                                        &dma->buflist[i]->idx,
-                                        sizeof(request.list[0].idx))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].total,
-                                        &dma->buflist[i]->total,
-                                        sizeof(request.list[0].total))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].used,
-                                        &zero,
-                                        sizeof(zero))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       address = virtual + dma->buflist[i]->offset;
-                       if (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);
-
-       if (copy_to_user((drm_buf_map_t *)arg,
-                        &request,
-                        sizeof(request)))
-               return -EFAULT;
-
-       return retcode;
-}
index d978d53e12aba7a0f3c478669faefab32c441aaf..d04473b9698d6d4805c7ca4cf39c71e527d26e55 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Gareth Hughes <gareth@valinux.com>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
 
 #include <linux/interrupt.h>   /* For task queue support */
 #include <linux/delay.h>
 
+#define R128_FIFO_DEBUG                0
 
-/* FIXME: Temporary CCE packet buffer */
-u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32)));
 
 /* CCE microcode (from ATI) */
 static u32 r128_cce_microcode[] = {
@@ -86,26 +85,6 @@ static u32 r128_cce_microcode[] = {
 };
 
 
-#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
-
-#define DO_REMAPFREE(_m)                                                    \
-       do {                                                                \
-               if ((_m)->handle && (_m)->size)                             \
-                       drm_ioremapfree((_m)->handle, (_m)->size);          \
-       } while (0)
-
-#define DO_FIND_MAP(_m, _o)                                                 \
-       do {                                                                \
-               int _i;                                                     \
-               for (_i = 0; _i < dev->map_count; _i++) {                   \
-                       if (dev->maplist[_i]->offset == _o) {               \
-                               _m = dev->maplist[_i];                      \
-                               break;                                      \
-                       }                                                   \
-               }                                                           \
-       } while (0)
-
-
 int R128_READ_PLL(drm_device_t *dev, int addr)
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
@@ -114,7 +93,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr)
        return R128_READ(R128_CLOCK_CNTL_DATA);
 }
 
-#if 0
+#if R128_FIFO_DEBUG
 static void r128_status( drm_r128_private_t *dev_priv )
 {
        printk( "GUI_STAT           = 0x%08x\n",
@@ -152,7 +131,9 @@ static int r128_do_pixcache_flush( drm_r128_private_t *dev_priv )
                udelay( 1 );
        }
 
+#if R128_FIFO_DEBUG
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+#endif
        return -EBUSY;
 }
 
@@ -166,16 +147,18 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
                udelay( 1 );
        }
 
+#if R128_FIFO_DEBUG
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+#endif
        return -EBUSY;
 }
 
-static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
+int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
 {
        int i, ret;
 
        ret = r128_do_wait_for_fifo( dev_priv, 64 );
-       if ( !ret ) return ret;
+       if ( ret < 0 ) return ret;
 
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
                if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
@@ -185,7 +168,9 @@ static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
                udelay( 1 );
        }
 
+#if R128_FIFO_DEBUG
        DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+#endif
        return -EBUSY;
 }
 
@@ -199,6 +184,8 @@ static void r128_cce_load_microcode( drm_r128_private_t *dev_priv )
 {
        int i;
 
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
        r128_do_wait_for_idle( dev_priv );
 
        R128_WRITE( R128_PM4_MICROCODE_ADDR, 0 );
@@ -224,12 +211,12 @@ static void r128_do_cce_flush( drm_r128_private_t *dev_priv )
 
 /* Wait for the CCE to go idle.
  */
-static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
+int r128_do_cce_idle( drm_r128_private_t *dev_priv )
 {
        int i;
 
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-               if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
+               if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) {
                        int pm4stat = R128_READ( R128_PM4_STAT );
                        if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
                               dev_priv->cce_fifo_size ) &&
@@ -241,7 +228,7 @@ static int r128_do_cce_idle( drm_r128_private_t *dev_priv )
                udelay( 1 );
        }
 
-#if 0
+#if R128_FIFO_DEBUG
        DRM_ERROR( "failed!\n" );
        r128_status( dev_priv );
 #endif
@@ -263,19 +250,19 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv )
 }
 
 /* Reset the Concurrent Command Engine.  This will not flush any pending
- * commangs, so you must wait for the CCE command stream to complete
+ * commands, so you must wait for the CCE command stream to complete
  * before calling this routine.
  */
 static void r128_do_cce_reset( drm_r128_private_t *dev_priv )
 {
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
        R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
-       *dev_priv->ring.head = 0;
+       SET_RING_HEAD( &dev_priv->ring, 0 );
        dev_priv->ring.tail = 0;
 }
 
 /* Stop the Concurrent Command Engine.  This will not flush any pending
- * commangs, so you must flush the command stream and wait for the CCE
+ * commands, so you must flush the command stream and wait for the CCE
  * to go idle before calling this routine.
  */
 static void r128_do_cce_stop( drm_r128_private_t *dev_priv )
@@ -327,25 +314,49 @@ static int r128_do_engine_reset( drm_device_t *dev )
        return 0;
 }
 
-static void r128_cce_init_ring_buffer( drm_device_t *dev )
+static void r128_cce_init_ring_buffer( drm_device_t *dev,
+                                      drm_r128_private_t *dev_priv )
 {
-       drm_r128_private_t *dev_priv = dev->dev_private;
        u32 ring_start;
        u32 tmp;
 
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
        /* The manual (p. 2) says this address is in "VM space".  This
         * means it's an offset from the start of AGP space.
         */
-       ring_start = dev_priv->cce_ring->offset - dev->agp->base;
+#if __REALLY_HAVE_AGP
+       if ( !dev_priv->is_pci )
+               ring_start = dev_priv->cce_ring->offset - dev->agp->base;
+       else
+#endif
+               ring_start = dev_priv->cce_ring->offset - dev->sg->handle;
+
        R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
 
        R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
        R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
 
        /* DL_RPTR_ADDR is a physical address in AGP space. */
-       *dev_priv->ring.head = 0;
-       R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
-                   dev_priv->ring_rptr->offset );
+       SET_RING_HEAD( &dev_priv->ring, 0 );
+
+       if ( !dev_priv->is_pci ) {
+               R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+                           dev_priv->ring_rptr->offset );
+       } else {
+               drm_sg_mem_t *entry = dev->sg;
+               unsigned long tmp_ofs, page_ofs;
+
+               tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
+               page_ofs = tmp_ofs >> PAGE_SHIFT;
+
+               R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+                           virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+               DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+                          virt_to_bus(entry->pagelist[page_ofs]->virtual),
+                          entry->handle + tmp_ofs );
+       }
 
        /* Set watermark control */
        R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
@@ -365,37 +376,35 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev )
 static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
 {
        drm_r128_private_t *dev_priv;
-        int i;
+       struct list_head *list;
+
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       dev_priv = drm_alloc( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
+       dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
        if ( dev_priv == NULL )
                return -ENOMEM;
-       dev->dev_private = (void *)dev_priv;
 
        memset( dev_priv, 0, sizeof(drm_r128_private_t) );
 
        dev_priv->is_pci = init->is_pci;
 
-       /* GH: We don't support PCI cards until PCI GART is implemented.
-        * Fail here so we can remove all checks for PCI cards around
-        * the CCE ring code.
-        */
-       if ( dev_priv->is_pci ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+       if ( dev_priv->is_pci && !dev->sg ) {
+               DRM_ERROR( "PCI GART memory not allocated!\n" );
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
                return -EINVAL;
        }
 
        dev_priv->usec_timeout = init->usec_timeout;
        if ( dev_priv->usec_timeout < 1 ||
             dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+               DRM_DEBUG( "TIMEOUT problem!\n" );
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
                return -EINVAL;
        }
 
        dev_priv->cce_mode = init->cce_mode;
-       dev_priv->cce_secure = init->cce_secure;
 
        /* GH: Simple idle check.
         */
@@ -409,8 +418,9 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
             ( init->cce_mode != R128_PM4_128BM_64INDBM ) &&
             ( init->cce_mode != R128_PM4_64BM_128INDBM ) &&
             ( init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM ) ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+               DRM_DEBUG( "Bad cce_mode!\n" );
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
                return -EINVAL;
        }
 
@@ -435,13 +445,30 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
                break;
        }
 
-       dev_priv->fb_bpp        = init->fb_bpp;
+       switch ( init->fb_bpp ) {
+       case 16:
+               dev_priv->color_fmt = R128_DATATYPE_RGB565;
+               break;
+       case 32:
+       default:
+               dev_priv->color_fmt = R128_DATATYPE_ARGB8888;
+               break;
+       }
        dev_priv->front_offset  = init->front_offset;
        dev_priv->front_pitch   = init->front_pitch;
        dev_priv->back_offset   = init->back_offset;
        dev_priv->back_pitch    = init->back_pitch;
 
-       dev_priv->depth_bpp     = init->depth_bpp;
+       switch ( init->depth_bpp ) {
+       case 16:
+               dev_priv->depth_fmt = R128_DATATYPE_RGB565;
+               break;
+       case 24:
+       case 32:
+       default:
+               dev_priv->depth_fmt = R128_DATATYPE_ARGB8888;
+               break;
+       }
        dev_priv->depth_offset  = init->depth_offset;
        dev_priv->depth_pitch   = init->depth_pitch;
        dev_priv->span_offset   = init->span_offset;
@@ -456,39 +483,99 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
                                         (dev_priv->span_offset >> 5));
 
-       /* FIXME: We want multiple shared areas, including one shared
-        * only by the X Server and kernel module.
-        */
-       for ( i = 0 ; i < dev->map_count ; i++ ) {
-               if ( dev->maplist[i]->type == _DRM_SHM ) {
-                       dev_priv->sarea = dev->maplist[i];
-                       break;
-               }
+       list_for_each(list, &dev->maplist->head) {
+               drm_map_list_t *r_list = (drm_map_list_t *)list;
+               if( r_list->map &&
+                   r_list->map->type == _DRM_SHM &&
+                   r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+                       dev_priv->sarea = r_list->map;
+                       break;
+               }
+       }
+       if(!dev_priv->sarea) {
+               DRM_ERROR("could not find sarea!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
        }
 
-       DO_FIND_MAP( dev_priv->fb, init->fb_offset );
-       DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
-       DO_FIND_MAP( dev_priv->cce_ring, init->ring_offset );
-       DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
-       DO_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+       DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
+       if(!dev_priv->fb) {
+               DRM_ERROR("could not find framebuffer!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+       if(!dev_priv->mmio) {
+               DRM_ERROR("could not find mmio region!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset );
+       if(!dev_priv->cce_ring) {
+               DRM_ERROR("could not find cce ring region!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
+       if(!dev_priv->ring_rptr) {
+               DRM_ERROR("could not find ring read pointer!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+       if(!dev_priv->buffers) {
+               DRM_ERROR("could not find dma buffer region!\n");
+               dev->dev_private = (void *)dev_priv;
+               r128_do_cleanup_cce( dev );
+               return -EINVAL;
+       }
 
        if ( !dev_priv->is_pci ) {
-               DO_FIND_MAP( dev_priv->agp_textures,
-                            init->agp_textures_offset );
+               DRM_FIND_MAP( dev_priv->agp_textures,
+                             init->agp_textures_offset );
+               if(!dev_priv->agp_textures) {
+                       DRM_ERROR("could not find agp texture region!\n");
+                       dev->dev_private = (void *)dev_priv;
+                       r128_do_cleanup_cce( dev );
+                       return -EINVAL;
+               }
        }
 
        dev_priv->sarea_priv =
                (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
                                     init->sarea_priv_offset);
 
-       DO_REMAP( dev_priv->cce_ring );
-       DO_REMAP( dev_priv->ring_rptr );
-       DO_REMAP( dev_priv->buffers );
-#if 0
        if ( !dev_priv->is_pci ) {
-               DO_REMAP( dev_priv->agp_textures );
+               DRM_IOREMAP( dev_priv->cce_ring );
+               DRM_IOREMAP( dev_priv->ring_rptr );
+               DRM_IOREMAP( dev_priv->buffers );
+               if(!dev_priv->cce_ring->handle ||
+                  !dev_priv->ring_rptr->handle ||
+                  !dev_priv->buffers->handle) {
+                       DRM_ERROR("Could not ioremap agp regions!\n");
+                       dev->dev_private = (void *)dev_priv;
+                       r128_do_cleanup_cce( dev );
+                       return -ENOMEM;
+               }
+       } else {
+               dev_priv->cce_ring->handle =
+                       (void *)dev_priv->cce_ring->offset;
+               dev_priv->ring_rptr->handle =
+                       (void *)dev_priv->ring_rptr->offset;
+               dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
        }
+
+#if __REALLY_HAVE_AGP
+       if ( !dev_priv->is_pci )
+               dev_priv->cce_buffers_offset = dev->agp->base;
+       else
 #endif
+               dev_priv->cce_buffers_offset = dev->sg->handle;
 
        dev_priv->ring.head = ((__volatile__ u32 *)
                               dev_priv->ring_rptr->handle);
@@ -497,11 +584,13 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
                              + init->ring_size / sizeof(u32));
        dev_priv->ring.size = init->ring_size;
-       dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+       dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
 
        dev_priv->ring.tail_mask =
                (dev_priv->ring.size / sizeof(u32)) - 1;
 
+       dev_priv->ring.high_mark = 128;
+
        dev_priv->sarea_priv->last_frame = 0;
        R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
 
@@ -509,29 +598,41 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        R128_WRITE( R128_LAST_DISPATCH_REG,
                    dev_priv->sarea_priv->last_dispatch );
 
-       r128_cce_init_ring_buffer( dev );
+       if ( dev_priv->is_pci ) {
+               dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
+               if ( !dev_priv->phys_pci_gart ) {
+                       DRM_ERROR( "failed to init PCI GART!\n" );
+                       dev->dev_private = (void *)dev_priv;
+                       r128_do_cleanup_cce( dev );
+                       return -ENOMEM;
+               }
+               R128_WRITE( R128_PCI_GART_PAGE,
+                           virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+       }
+
+       r128_cce_init_ring_buffer( dev, dev_priv );
        r128_cce_load_microcode( dev_priv );
+
+       dev->dev_private = (void *)dev_priv;
+
        r128_do_engine_reset( dev );
 
        return 0;
 }
 
-static int r128_do_cleanup_cce( drm_device_t *dev )
+int r128_do_cleanup_cce( drm_device_t *dev )
 {
        if ( dev->dev_private ) {
                drm_r128_private_t *dev_priv = dev->dev_private;
 
-               DO_REMAPFREE( dev_priv->cce_ring );
-               DO_REMAPFREE( dev_priv->ring_rptr );
-               DO_REMAPFREE( dev_priv->buffers );
-#if 0
                if ( !dev_priv->is_pci ) {
-                       DO_REMAPFREE( dev_priv->agp_textures );
+                       DRM_IOREMAPFREE( dev_priv->cce_ring );
+                       DRM_IOREMAPFREE( dev_priv->ring_rptr );
+                       DRM_IOREMAPFREE( dev_priv->buffers );
                }
-#endif
 
-               drm_free( dev->dev_private, sizeof(drm_r128_private_t),
-                         DRM_MEM_DRIVER );
+               DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
+                          DRM_MEM_DRIVER );
                dev->dev_private = NULL;
        }
 
@@ -545,6 +646,8 @@ int r128_cce_init( struct inode *inode, struct file *filp,
         drm_device_t *dev = priv->dev;
        drm_r128_init_t init;
 
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
        if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
                return -EFAULT;
 
@@ -566,11 +669,8 @@ int r128_cce_start( struct inode *inode, struct file *filp,
        drm_r128_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
        if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
                DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
                return 0;
@@ -594,11 +694,7 @@ int r128_cce_stop( struct inode *inode, struct file *filp,
        int ret;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) )
                return -EFAULT;
@@ -640,11 +736,8 @@ int r128_cce_reset( struct inode *inode, struct file *filp,
        drm_r128_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
        if ( !dev_priv ) {
                DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
                return -EINVAL;
@@ -666,11 +759,7 @@ int r128_cce_idle( struct inode *inode, struct file *filp,
        drm_r128_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( dev_priv->cce_running ) {
                r128_do_cce_flush( dev_priv );
@@ -686,16 +775,71 @@ int r128_engine_reset( struct inode *inode, struct file *filp,
         drm_device_t *dev = priv->dev;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        return r128_do_engine_reset( dev );
 }
 
 
+/* ================================================================
+ * Fullscreen mode
+ */
+
+static int r128_do_init_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
+       dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
+
+       R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL,
+                   dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL );
+
+       dev_priv->page_flipping = 1;
+       dev_priv->current_page = 0;
+
+       return 0;
+}
+
+int r128_do_cleanup_pageflip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
+       R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+       dev_priv->page_flipping = 0;
+       dev_priv->current_page = 0;
+
+       return 0;
+}
+
+int r128_fullscreen( struct inode *inode, struct file *filp,
+                    unsigned int cmd, unsigned long arg )
+{
+        drm_file_t *priv = filp->private_data;
+        drm_device_t *dev = priv->dev;
+       drm_r128_fullscreen_t fs;
+
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) )
+               return -EFAULT;
+
+       switch ( fs.func ) {
+       case R128_INIT_FULLSCREEN:
+               return r128_do_init_pageflip( dev );
+       case R128_CLEANUP_FULLSCREEN:
+               return r128_do_cleanup_pageflip( dev );
+       }
+
+       return -EINVAL;
+}
+
+
 /* ================================================================
  * Freelist management
  */
@@ -712,8 +856,8 @@ static int r128_freelist_init( drm_device_t *dev )
        drm_r128_freelist_t *entry;
        int i;
 
-       dev_priv->head = drm_alloc( sizeof(drm_r128_freelist_t),
-                                   DRM_MEM_DRIVER );
+       dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t),
+                                    DRM_MEM_DRIVER );
        if ( dev_priv->head == NULL )
                return -ENOMEM;
 
@@ -724,8 +868,8 @@ static int r128_freelist_init( drm_device_t *dev )
                buf = dma->buflist[i];
                buf_priv = buf->dev_private;
 
-               entry = drm_alloc( sizeof(drm_r128_freelist_t),
-                                  DRM_MEM_DRIVER );
+               entry = DRM(alloc)( sizeof(drm_r128_freelist_t),
+                                   DRM_MEM_DRIVER );
                if ( !entry ) return -ENOMEM;
 
                entry->age = R128_BUFFER_FREE;
@@ -802,7 +946,7 @@ void r128_freelist_reset( drm_device_t *dev )
 
 
 /* ================================================================
- * CCE packet submission
+ * CCE command submission
  */
 
 int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
@@ -811,378 +955,17 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n )
        int i;
 
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-               ring->space = *ring->head - ring->tail;
-               if ( ring->space <= 0 )
-                       ring->space += ring->size;
-
+               r128_update_ring_snapshot( ring );
                if ( ring->space >= n )
                        return 0;
-
                udelay( 1 );
        }
 
+       /* FIXME: This is being ignored... */
+       DRM_ERROR( "failed!\n" );
        return -EBUSY;
 }
 
-void r128_update_ring_snapshot( drm_r128_private_t *dev_priv )
-{
-       drm_r128_ring_buffer_t *ring = &dev_priv->ring;
-
-       ring->space = *ring->head - ring->tail;
-#if R128_PERFORMANCE_BOXES
-       if ( ring->space == 0 )
-               atomic_inc( &dev_priv->idle_count );
-#endif
-       if ( ring->space <= 0 )
-               ring->space += ring->size;
-}
-
-#if 0
-static int r128_verify_command( drm_r128_private_t *dev_priv,
-                               u32 cmd, int *size )
-{
-       int writing = 1;
-
-       *size = 0;
-
-       switch ( cmd & R128_CCE_PACKET_MASK ) {
-       case R128_CCE_PACKET0:
-               if ( (cmd & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2) &&
-                    (cmd & R128_CCE_PACKET0_REG_MASK) !=
-                    (R128_PM4_VC_FPU_SETUP >> 2) ) {
-                       writing = 0;
-               }
-               *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
-               break;
-
-       case R128_CCE_PACKET1:
-               if ( (cmd & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2) &&
-                    (cmd & R128_CCE_PACKET1_REG0_MASK) !=
-                    (R128_PM4_VC_FPU_SETUP >> 2) ) {
-                       writing = 0;
-               }
-               if ( (cmd & R128_CCE_PACKET1_REG1_MASK) <= (0x1004 << 9) &&
-                    (cmd & R128_CCE_PACKET1_REG1_MASK) !=
-                    (R128_PM4_VC_FPU_SETUP << 9) ) {
-                       writing = 0;
-               }
-               *size = 3;
-               break;
-
-       case R128_CCE_PACKET2:
-               break;
-
-       case R128_CCE_PACKET3:
-               *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2;
-               break;
-
-       }
-
-       return writing;
-}
-
-static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv,
-                                          u32 *commands, int *count )
-{
-#if 0
-       int write = dev_priv->sarea_priv->ring_write;
-       int *write_ptr = dev_priv->ring_start + write;
-       int c = *count;
-       u32 tmp = 0;
-       int psize = 0;
-       int writing = 1;
-       int timeout;
-
-       while ( c > 0 ) {
-               tmp = *commands++;
-               if ( !psize ) {
-                       writing = r128_verify_command( dev_priv, tmp, &psize );
-               }
-               psize--;
-
-               if ( writing ) {
-                       write++;
-                       *write_ptr++ = tmp;
-               }
-               if ( write >= dev_priv->ring_entries ) {
-                       write = 0;
-                       write_ptr = dev_priv->ring_start;
-               }
-               timeout = 0;
-               while ( write == *dev_priv->ring_read_ptr ) {
-                       R128_READ( R128_PM4_BUFFER_DL_RPTR );
-                       if ( timeout++ >= dev_priv->usec_timeout )
-                               return -EBUSY;
-                       udelay( 1 );
-               }
-               c--;
-       }
-
-       if ( write < 32 ) {
-               memcpy( dev_priv->ring_end,
-                       dev_priv->ring_start,
-                       write * sizeof(u32) );
-       }
-
-       /* Make sure WC cache has been flushed */
-       r128_flush_write_combine();
-
-       dev_priv->sarea_priv->ring_write = write;
-       R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
-
-       *count = 0;
-#endif
-       return 0;
-}
-
-static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv,
-                                            u32 *commands, int *count )
-{
-#if 0
-       int write = dev_priv->sarea_priv->ring_write;
-       int *write_ptr = dev_priv->ring_start + write;
-       int c = *count;
-       int timeout;
-
-       while ( c > 0 ) {
-               write++;
-               *write_ptr++ = *commands++;
-               if ( write >= dev_priv->ring_entries ) {
-                       write = 0;
-                       write_ptr = dev_priv->ring_start;
-               }
-
-               timeout = 0;
-               while ( write == *dev_priv->ring_read_ptr ) {
-                       R128_READ( R128_PM4_BUFFER_DL_RPTR );
-                       if ( timeout++ >= dev_priv->usec_timeout )
-                               return -EBUSY;
-                       udelay( 1 );
-               }
-               c--;
-       }
-
-       if ( write < 32 ) {
-               memcpy( dev_priv->ring_end,
-                       dev_priv->ring_start,
-                       write * sizeof(u32) );
-       }
-
-       /* Make sure WC cache has been flushed */
-       r128_flush_write_combine();
-
-       dev_priv->sarea_priv->ring_write = write;
-       R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write );
-
-       *count = 0;
-#endif
-       return 0;
-}
-#endif
-
-/* Internal packet submission routine.  This uses the insecure versions
- * of the packet submission functions, and thus should only be used for
- * packets generated inside the kernel module.
- */
-int r128_do_submit_packet( drm_r128_private_t *dev_priv,
-                          u32 *buffer, int count )
-{
-       int c = count;
-       int ret = 0;
-
-#if 0
-       int left = 0;
-
-       if ( c >= dev_priv->ring_entries ) {
-               c = dev_priv->ring_entries - 1;
-               left = count - c;
-       }
-
-       /* Since this is only used by the kernel we can use the
-        * insecure ring buffer submit packet routine.
-        */
-       ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c );
-       c += left;
-#endif
-
-       return ( ret < 0 ) ? ret : c;
-}
-
-/* External packet submission routine.  This uses the secure versions
- * by default, and can thus submit packets received from user space.
- */
-int r128_cce_packet( struct inode *inode, struct file *filp,
-                    unsigned int cmd, unsigned long arg )
-{
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
-       drm_r128_private_t *dev_priv = dev->dev_private;
-       drm_r128_packet_t packet;
-       u32 *buffer;
-       int c;
-       int size;
-       int ret = 0;
-
-#if 0
-       /* GH: Disable packet submission for now.
-        */
-       return -EINVAL;
-#endif
-
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "r128_submit_packet called without lock held\n" );
-               return -EINVAL;
-       }
-
-       if ( copy_from_user( &packet, (drm_r128_packet_t *)arg,
-                            sizeof(packet) ) )
-               return -EFAULT;
-
-#if 0
-       c = packet.count;
-       size = c * sizeof(*buffer);
-
-       {
-               int left = 0;
-
-               if ( c >= dev_priv->ring_entries ) {
-                       c = dev_priv->ring_entries - 1;
-                       size = c * sizeof(*buffer);
-                       left = packet.count - c;
-               }
-
-               buffer = kmalloc( size, 0 );
-               if ( buffer == NULL)
-                       return -ENOMEM;
-               if ( copy_from_user( buffer, packet.buffer, size ) )
-                       return -EFAULT;
-
-               if ( dev_priv->cce_secure ) {
-                       ret = r128_submit_packet_ring_secure( dev_priv,
-                                                             buffer, &c );
-               } else {
-                       ret = r128_submit_packet_ring_insecure( dev_priv,
-                                                               buffer, &c );
-               }
-               c += left;
-       }
-
-       kfree( buffer );
-#else
-       c = 0;
-#endif
-
-       packet.count = c;
-       if ( copy_to_user( (drm_r128_packet_t *)arg, &packet,
-                          sizeof(packet) ) )
-               return -EFAULT;
-
-       if ( ret ) {
-               return ret;
-       } else if ( c > 0 ) {
-               return -EAGAIN;
-       }
-       return 0;
-}
-
-#if 0
-static int r128_send_vertbufs( drm_device_t *dev, drm_r128_vertex_t *v )
-{
-       drm_device_dma_t    *dma      = dev->dma;
-       drm_r128_private_t  *dev_priv = dev->dev_private;
-       drm_r128_buf_priv_t *buf_priv;
-       drm_buf_t           *buf;
-       int                  i, ret;
-       RING_LOCALS;
-
-       /* Make sure we have valid data */
-       for (i = 0; i < v->send_count; i++) {
-               int idx = v->send_indices[i];
-
-               if (idx < 0 || idx >= dma->buf_count) {
-                       DRM_ERROR("Index %d (of %d max)\n",
-                                 idx, dma->buf_count - 1);
-                       return -EINVAL;
-               }
-               buf = dma->buflist[idx];
-               if (buf->pid != current->pid) {
-                       DRM_ERROR("Process %d using buffer owned by %d\n",
-                                 current->pid, buf->pid);
-                       return -EINVAL;
-               }
-               if (buf->pending) {
-                       DRM_ERROR("Sending pending buffer:"
-                                 " buffer %d, offset %d\n",
-                                 v->send_indices[i], i);
-                       return -EINVAL;
-               }
-       }
-
-       /* Wait for idle, if we've wrapped to make sure that all pending
-           buffers have been processed */
-       if (dev_priv->submit_age == R128_MAX_VBUF_AGE) {
-               if ((ret = r128_do_cce_idle(dev)) < 0) return ret;
-               dev_priv->submit_age = 0;
-               r128_freelist_reset(dev);
-       }
-
-       /* Make sure WC cache has been flushed (if in PIO mode) */
-       if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine();
-
-       /* FIXME: Add support for sending vertex buffer to the CCE here
-          instead of in client code.  The v->prim holds the primitive
-          type that should be drawn.  Loop over the list buffers in
-          send_indices[] and submit a packet for each VB.
-
-          This will require us to loop over the clip rects here as
-          well, which implies that we extend the kernel driver to allow
-          cliprects to be stored here.  Note that the cliprects could
-          possibly come from the X server instead of the client, but
-          this will require additional changes to the DRI to allow for
-          this optimization. */
-
-       /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */
-#if 0
-       cce_buffer[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0);
-       cce_buffer[1] = dev_priv->submit_age;
-
-       if ((ret = r128_do_submit_packet(dev, cce_buffer, 2)) < 0) {
-               /* Until we add support for sending VBs to the CCE in
-                  this routine, we can recover from this error.  After
-                  we add that support, we won't be able to easily
-                  recover, so we will probably have to implement
-                  another mechanism for handling timeouts from packets
-                  submitted directly by the kernel. */
-               return ret;
-       }
-#else
-       BEGIN_RING( 2 );
-
-       OUT_RING( CCE_PACKET0( R128_VB_AGE_REG, 0 ) );
-       OUT_RING( dev_priv->submit_age );
-
-       ADVANCE_RING();
-#endif
-       /* Now that the submit packet request has succeeded, we can mark
-           the buffers as pending */
-       for (i = 0; i < v->send_count; i++) {
-               buf = dma->buflist[v->send_indices[i]];
-               buf->pending = 1;
-
-               buf_priv      = buf->dev_private;
-               buf_priv->age = dev_priv->submit_age;
-       }
-
-       dev_priv->submit_age++;
-
-       return 0;
-}
-#endif
-
-
-
-
 static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
 {
        int i;
@@ -1215,15 +998,11 @@ int r128_cce_buffers( struct inode *inode, struct file *filp,
        int ret = 0;
        drm_dma_t d;
 
+       LOCK_TEST_WITH_RETURN( dev );
+
        if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
                return -EFAULT;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-
        /* Please don't send us buffers.
         */
        if ( d.send_count != 0 ) {
diff --git a/drivers/char/drm/r128_context.c b/drivers/char/drm/r128_context.c
deleted file mode 100644 (file)
index 0741e77..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/* r128_context.c -- IOCTLs for r128 contexts -*- linux-c -*-
- * Created: Mon Dec 13 09:51:35 1999 by faith@precisioninsight.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
- * 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.
- *
- * Author: Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "r128_drv.h"
-
-extern drm_ctx_t r128_res_ctx;
-
-static int r128_alloc_queue(drm_device_t *dev)
-{
-       return drm_ctxbitmap_next(dev);
-}
-
-int r128_context_switch(drm_device_t *dev, int old, int new)
-{
-        char        buf[64];
-
-        atomic_inc(&dev->total_ctx);
-
-        if (test_and_set_bit(0, &dev->context_flag)) {
-                DRM_ERROR("Reentering -- FIXME\n");
-                return -EBUSY;
-        }
-
-#if DRM_DMA_HISTOGRAM
-        dev->ctx_start = get_cycles();
-#endif
-
-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-        if (new == dev->last_context) {
-                clear_bit(0, &dev->context_flag);
-                return 0;
-        }
-
-        if (drm_flags & DRM_FLAG_NOCTX) {
-                r128_context_switch_complete(dev, new);
-        } else {
-                sprintf(buf, "C %d %d\n", old, new);
-                drm_write_string(dev, buf);
-        }
-
-        return 0;
-}
-
-int r128_context_switch_complete(drm_device_t *dev, int new)
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-
-        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. */
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                      - dev->ctx_start)]);
-
-#endif
-        clear_bit(0, &dev->context_flag);
-        wake_up(&dev->context_wait);
-
-        return 0;
-}
-
-
-int r128_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i],
-                                        &i,
-                                        sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-
-int r128_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = r128_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Skip kernel's context and get a new one. */
-               ctx.handle = r128_alloc_queue(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 (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int r128_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       if (ctx.flags==_DRM_CONTEXT_PRESERVED)
-               r128_res_ctx.handle=ctx.handle;
-       return 0;
-}
-
-int r128_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       /* This is 0, because we don't hanlde any context flags */
-       ctx.flags = 0;
-       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int r128_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return r128_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int r128_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       r128_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int r128_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       drm_ctxbitmap_free(dev, ctx.handle);
-
-       return 0;
-}
index 68a55d5dcbe1c2d90f63d0895c3c8b0a9b173024..0fc6a6cd16e79b32ac074b9ed2b7452b8af686a8 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
+ *    Kevin E. Martin <martin@valinux.com>
  */
 
-#ifndef _R128_DRM_H_
-#define _R128_DRM_H_
+#ifndef __R128_DRM_H__
+#define __R128_DRM_H__
 
 /* WARNING: If you change any of these defines, make sure to change the
  * defines in the X server file (r128_sarea.h)
 
 /* Vertex/indirect buffer size
  */
-#if 1
 #define R128_BUFFER_SIZE               16384
-#else
-#define R128_BUFFER_SIZE               (128 * 1024)
-#endif
 
 /* Byte offsets for indirect buffer data
  */
 #define R128_INDEX_PRIM_OFFSET         20
 #define R128_HOSTDATA_BLIT_OFFSET      32
 
-/* 2048x2048 @ 32bpp texture requires this many indirect buffers
- */
-#define R128_MAX_BLIT_BUFFERS          ((2048 * 2048 * 4) / R128_BUFFER_SIZE)
-
 /* Keep these small for testing.
  */
 #define R128_NR_SAREA_CLIPRECTS                12
@@ -98,7 +89,9 @@
 #define R128_LOG_TEX_GRANULARITY       16
 
 #define R128_NR_CONTEXT_REGS           12
-#define R128_TEX_MAXLEVELS             11
+
+#define R128_MAX_TEXTURE_LEVELS                11
+#define R128_MAX_TEXTURE_UNITS         2
 
 #endif /* __R128_SAREA_DEFINES__ */
 
@@ -137,28 +130,23 @@ typedef struct {
        unsigned int scale_3d_cntl;
 } drm_r128_context_regs_t;
 
-/* Setup registers for each texture unit */
+/* Setup registers for each texture unit
+ */
 typedef struct {
        unsigned int tex_cntl;
        unsigned int tex_combine_cntl;
        unsigned int tex_size_pitch;
-       unsigned int tex_offset[R128_TEX_MAXLEVELS];
+       unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
        unsigned int tex_border_color;
 } drm_r128_texture_regs_t;
 
 
-typedef struct drm_tex_region {
-       unsigned char next, prev;
-       unsigned char in_use;
-       int age;
-} drm_tex_region_t;
-
 typedef struct drm_r128_sarea {
        /* The channel for communication of state information to the kernel
         * on firing a vertex buffer.
         */
        drm_r128_context_regs_t context_state;
-       drm_r128_texture_regs_t tex_state[R128_NR_TEX_HEAPS];
+       drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS];
        unsigned int dirty;
        unsigned int vertsize;
        unsigned int vc_format;
@@ -187,7 +175,11 @@ typedef struct drm_r128_init {
                R128_INIT_CCE    = 0x01,
                R128_CLEANUP_CCE = 0x02
        } func;
+#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
        int sarea_priv_offset;
+#else
+       unsigned long sarea_priv_offset;
+#endif
        int is_pci;
        int cce_mode;
        int cce_secure;
@@ -201,12 +193,21 @@ typedef struct drm_r128_init {
        unsigned int depth_offset, depth_pitch;
        unsigned int span_offset;
 
+#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
        unsigned int fb_offset;
        unsigned int mmio_offset;
        unsigned int ring_offset;
        unsigned int ring_rptr_offset;
        unsigned int buffers_offset;
        unsigned int agp_textures_offset;
+#else
+       unsigned long fb_offset;
+       unsigned long mmio_offset;
+       unsigned long ring_offset;
+       unsigned long ring_rptr_offset;
+       unsigned long buffers_offset;
+       unsigned long agp_textures_offset;
+#endif
 } drm_r128_init_t;
 
 typedef struct drm_r128_cce_stop {
@@ -216,9 +217,15 @@ typedef struct drm_r128_cce_stop {
 
 typedef struct drm_r128_clear {
        unsigned int flags;
+#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
        int x, y, w, h;
+#endif
        unsigned int clear_color;
        unsigned int clear_depth;
+#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
+       unsigned int color_mask;
+       unsigned int depth_mask;
+#endif
 } drm_r128_clear_t;
 
 typedef struct drm_r128_vertex {
@@ -263,10 +270,18 @@ typedef struct drm_r128_stipple {
        unsigned int *mask;
 } drm_r128_stipple_t;
 
-typedef struct drm_r128_packet {
-       unsigned int *buffer;
-       int count;
-       int flags;
-} drm_r128_packet_t;
+typedef struct drm_r128_indirect {
+       int idx;
+       int start;
+       int end;
+       int discard;
+} drm_r128_indirect_t;
+
+typedef struct drm_r128_fullscreen {
+       enum {
+               R128_INIT_FULLSCREEN    = 0x01,
+               R128_CLEANUP_FULLSCREEN = 0x02
+       } func;
+} drm_r128_fullscreen_t;
 
 #endif
index dbfc9b7400d6a7d897a3acb9f57d05de6d6c9373..d4eda6c8c1207d327604ca11b21275c0b74259e3 100644 (file)
@@ -1,7 +1,7 @@
 /* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
  * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
  *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All Rights Reserved.
  *
  * 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
+ * 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.
+ * 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>
- *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
  */
 
 #include <linux/config.h>
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
+#include "ati_pcigart.h"
+
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "r128"
+#define DRIVER_DESC            "ATI Rage 128"
+#define DRIVER_DATE            "20010405"
+
+#define DRIVER_MAJOR           2
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      6
+
+#define DRIVER_IOCTLS                                                      \
+   [DRM_IOCTL_NR(DRM_IOCTL_DMA)]             = { r128_cce_buffers,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)]       = { r128_cce_init,     1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)]  = { r128_cce_start,    1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]      = { r128_engine_reset, 1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]       = { r128_cce_swap,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]      = { r128_cce_clear,    1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)]    = { r128_cce_indices,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)]       = { r128_cce_blit,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)]      = { r128_cce_depth,    1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
 
-#define R128_NAME              "r128"
-#define R128_DESC              "ATI Rage 128"
-#define R128_DATE              "20001215"
-#define R128_MAJOR             2
-#define R128_MINOR             1
-#define R128_PATCHLEVEL                2
-
-static drm_device_t    r128_device;
-drm_ctx_t              r128_res_ctx;
-
-static struct file_operations r128_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#endif
-       open:    r128_open,
-       flush:   drm_flush,
-       release: r128_release,
-       ioctl:   r128_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
-
-static struct miscdevice      r128_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  R128_NAME,
-       fops:  &r128_fops,
-};
 
-static drm_ioctl_desc_t              r128_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]      = { r128_version,      0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]   = { drm_getunique,     0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]    = { drm_getmagic,      0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]    = { drm_irq_busid,     0, 1 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]   = { drm_setunique,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]        = { drm_block,         1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]      = { drm_unblock,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]   = { drm_authmagic,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]      = { drm_addmap,        1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]     = { r128_addbufs,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]    = { drm_markbufs,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]    = { drm_infobufs,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]     = { r128_mapbufs,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]    = { drm_freebufs,      1, 0 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]      = { r128_addctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]       = { r128_rmctx,        1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]      = { r128_modctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]      = { r128_getctx,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]   = { r128_switchctx,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]      = { r128_newctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]      = { r128_resctx,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]     = { drm_adddraw,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]      = { drm_rmdraw,        1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]          = { r128_cce_buffers,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]         = { r128_lock,         1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]       = { r128_unlock,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]       = { drm_finish,        1, 0 },
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]  = { drm_agp_acquire,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]  = { drm_agp_release,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]   = { drm_agp_enable,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]     = { drm_agp_info,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]    = { drm_agp_alloc,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]     = { drm_agp_free,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]     = { drm_agp_bind,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]   = { drm_agp_unbind,    1, 1 },
+#if 0
+/* GH: Count data sent to card via ring or vertex/indirect buffers.
+ */
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
 #endif
 
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)]    = { r128_cce_init,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)]  = { r128_cce_stop,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)]  = { r128_cce_idle,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]   = { r128_engine_reset, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]    = { r128_cce_swap,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]   = { r128_cce_clear,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]  = { r128_cce_vertex,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)]    = { r128_cce_blit,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)]   = { r128_cce_depth,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)]  = { r128_cce_packet,   1, 0 },
-};
-#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)
-
-#ifdef MODULE
-static char                  *r128 = NULL;
-#endif
 
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("r128");
-MODULE_PARM(r128, "s");
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
 #ifndef MODULE
-/* r128_options is called by the kernel to parse command-line options
+/* DRM(options) is called by the kernel to parse command-line options
  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
  * routine, drm_parse_drm.
  */
 
-static int __init r128_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init r128_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("r128=", r128_options);
+__setup( DRIVER_NAME "=", r128_options );
 #endif
 
-static int r128_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       drm_dma_setup(dev);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       r128_res_ctx.handle=-1;
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int r128_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-                               /* Clear AGP information */
-       if (dev->agp) {
-               drm_agp_mem_t *entry;
-               drm_agp_mem_t *nexte;
-
-                               /* Remove AGP resources, but leave dev->agp
-                                   intact until r128_cleanup is called. */
-               for (entry = dev->agp->memory; entry; entry = nexte) {
-                       nexte = entry->next;
-                       if (entry->bound) drm_unbind_agp(entry->memory);
-                       drm_free_agp(entry->memory, entry->pages);
-                       drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               }
-               dev->agp->memory = NULL;
-
-               if (dev->agp->acquired) _drm_agp_release();
-
-               dev->agp->acquired = 0;
-               dev->agp->enabled  = 0;
-       }
-#endif
-
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
-#endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                   handled in the AGP/GART driver. */
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       drm_dma_takedown(dev);
-
-       dev->queue_count     = 0;
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-/* r128_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init r128_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &r128_device;
-
-       DRM_DEBUG("\n");
-
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
-
-#ifdef MODULE
-       drm_parse_options(r128);
-#endif
-
-       if ((retcode = misc_register(&r128_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", R128_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, r128_misc.minor);
-       dev->name   = R128_NAME;
-
-       drm_mem_init();
-       drm_proc_init(dev);
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       dev->agp    = drm_agp_init();
-       if (dev->agp == NULL) {
-               DRM_ERROR("Cannot initialize agpgart module.\n");
-               drm_proc_cleanup();
-               misc_deregister(&r128_misc);
-               r128_takedown(dev);
-               return -ENOMEM;
-       }
-
-#ifdef CONFIG_MTRR
-       dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
-                                     dev->agp->agp_info.aper_size*1024*1024,
-                                     MTRR_TYPE_WRCOMB,
-                                     1);
-#endif
-#endif
-
-       if((retcode = drm_ctxbitmap_init(dev))) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               drm_proc_cleanup();
-               misc_deregister(&r128_misc);
-               r128_takedown(dev);
-               return retcode;
-       }
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-                R128_NAME,
-                R128_MAJOR,
-                R128_MINOR,
-                R128_PATCHLEVEL,
-                R128_DATE,
-                r128_misc.minor);
-
-       return 0;
-}
-
-/* r128_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit r128_cleanup(void)
-{
-       drm_device_t          *dev = &r128_device;
-
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&r128_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       drm_ctxbitmap_cleanup(dev);
-       r128_takedown(dev);
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       if (dev->agp) {
-               drm_agp_uninit();
-               drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-               dev->agp = NULL;
-       }
-#endif
-}
-
-module_init(r128_init);
-module_exit(r128_cleanup);
-
-
-int r128_version(struct inode *inode, struct file *filp,
-                unsigned int cmd, unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                   \
-       len = strlen(value);                                    \
-       if (len > name##_len) len = name##_len;                 \
-       name##_len = strlen(value);                             \
-       if (len && name) {                                      \
-               if (copy_to_user(name, value, len))             \
-                       return -EFAULT;                         \
-       }
-
-       version.version_major      = R128_MAJOR;
-       version.version_minor      = R128_MINOR;
-       version.version_patchlevel = R128_PATCHLEVEL;
-
-       DRM_COPY(version.name, R128_NAME);
-       DRM_COPY(version.date, R128_DATE);
-       DRM_COPY(version.desc, R128_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int r128_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &r128_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return r128_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       return retcode;
-}
-
-int r128_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev = priv->dev;
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_release(inode, filp))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_close);
-               spin_lock(&dev->count_lock);
-               if (!--dev->open_count) {
-                       if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                               DRM_ERROR("Device busy: %d %d\n",
-                                         atomic_read(&dev->ioctl_count),
-                                         dev->blocked);
-                               spin_unlock(&dev->count_lock);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return r128_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return retcode;
-}
-
-/* r128_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-int r128_ioctl(struct inode *inode, struct file *filp,
-              unsigned int cmd, unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= R128_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &r128_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                          || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-#if 0
-       if ( retcode ) {
-               DRM_INFO( "%s 0x%x ret = %d\n", __FUNCTION__, nr, retcode );
-       }
-#endif
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-int r128_lock(struct inode *inode, struct file *filp,
-             unsigned int cmd, unsigned long arg)
-{
-        drm_file_t        *priv   = filp->private_data;
-        drm_device_t      *dev    = priv->dev;
-        DECLARE_WAITQUEUE(entry, current);
-        int               ret   = 0;
-        drm_lock_t        lock;
-#if DRM_DMA_HISTOGRAM
-        cycles_t          start;
-
-        dev->lck_start = start = get_cycles();
-#endif
-
-        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-        if (lock.context == DRM_KERNEL_CONTEXT) {
-                DRM_ERROR("Process %d using kernel context %d\n",
-                          current->pid, lock.context);
-                return -EINVAL;
-        }
-
-        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                  lock.context, current->pid, dev->lock.hw_lock->lock,
-                  lock.flags);
-
-        if (lock.context < 0)
-                return -EINVAL;
-
-        if (!ret) {
-                add_wait_queue(&dev->lock.lock_queue, &entry);
-                for (;;) {
-                        current->state = TASK_INTERRUPTIBLE;
-                        if (!dev->lock.hw_lock) {
-                                /* Device has been unregistered */
-                                ret = -EINTR;
-                                break;
-                        }
-                        if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                          lock.context)) {
-                                dev->lock.pid       = current->pid;
-                                dev->lock.lock_time = jiffies;
-                                atomic_inc(&dev->total_locks);
-                                break;  /* Got lock */
-                        }
-
-                                /* Contention */
-                        atomic_inc(&dev->total_sleeps);
-                        schedule();
-                        if (signal_pending(current)) {
-                                ret = -ERESTARTSYS;
-                                break;
-                        }
-                }
-                current->state = TASK_RUNNING;
-                remove_wait_queue(&dev->lock.lock_queue, &entry);
-        }
-
-        if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-                if (lock.flags & _DRM_LOCK_READY) {
-                               /* Wait for space in DMA/FIFO */
-               }
-                if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                               /* Make hardware quiescent */
-                       DRM_DEBUG( "not quiescent!\n" );
-#if 0
-                        r128_quiescent(dev);
-#endif
-               }
-        }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != r128_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY/4;
-       }
-#endif
-        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
-#endif
-
-        return ret;
-}
-
-
-int r128_unlock(struct inode *inode, struct file *filp,
-               unsigned int cmd, unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-                               /* FIXME: Try to send data to card here */
-       if (!dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != r128_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY;
-       }
-#endif
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
+#include "drm_scatter.h"
index ab702001489a0578b698e0aa60eb1166cf8e3238..0ef94e4544bb3637f8e94001dd87f010b6ea9fa2 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Rickard E. (Rik) Faith <faith@valinux.com>
- *   Kevin E. Martin <martin@valinux.com>
- *   Gareth Hughes <gareth@valinux.com>
- *
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Kevin E. Martin <martin@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ *    Michel Dänzer <daenzerm@student.ethz.ch>
  */
 
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
+#define GET_RING_HEAD( ring )          le32_to_cpu( *(ring)->head )
+#define SET_RING_HEAD( ring, val )     *(ring)->head = cpu_to_le32( val )
+
 typedef struct drm_r128_freelist {
        unsigned int age;
        drm_buf_t *buf;
@@ -51,6 +54,8 @@ typedef struct drm_r128_ring_buffer {
        u32 tail;
        u32 tail_mask;
        int space;
+
+       int high_mark;
 } drm_r128_ring_buffer_t;
 
 typedef struct drm_r128_private {
@@ -59,7 +64,6 @@ typedef struct drm_r128_private {
 
        int cce_mode;
        int cce_fifo_size;
-       int cce_secure;
        int cce_running;
 
        drm_r128_freelist_t *head;
@@ -67,16 +71,23 @@ typedef struct drm_r128_private {
 
        int usec_timeout;
        int is_pci;
+       unsigned long phys_pci_gart;
+       unsigned long cce_buffers_offset;
 
        atomic_t idle_count;
 
-       unsigned int fb_bpp;
+       int page_flipping;
+       int current_page;
+       u32 crtc_offset;
+       u32 crtc_offset_cntl;
+
+       u32 color_fmt;
        unsigned int front_offset;
        unsigned int front_pitch;
        unsigned int back_offset;
        unsigned int back_pitch;
 
-       unsigned int depth_bpp;
+       u32 depth_fmt;
        unsigned int depth_offset;
        unsigned int depth_pitch;
        unsigned int span_offset;
@@ -103,18 +114,6 @@ typedef struct drm_r128_buf_priv {
        drm_r128_freelist_t *list_entry;
 } drm_r128_buf_priv_t;
 
-                               /* r128_drv.c */
-extern int  r128_version( struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg );
-extern int  r128_open( struct inode *inode, struct file *filp );
-extern int  r128_release( struct inode *inode, struct file *filp );
-extern int  r128_ioctl( struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg );
-extern int  r128_lock( struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg );
-extern int  r128_unlock( struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg );
-
                                /* r128_cce.c */
 extern int r128_cce_init( struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg );
@@ -128,7 +127,7 @@ extern int r128_cce_idle( struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg );
 extern int r128_engine_reset( struct inode *inode, struct file *filp,
                              unsigned int cmd, unsigned long arg );
-extern int r128_cce_packet( struct inode *inode, struct file *filp,
+extern int r128_fullscreen( struct inode *inode, struct file *filp,
                            unsigned int cmd, unsigned long arg );
 extern int r128_cce_buffers( struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg );
@@ -137,7 +136,18 @@ extern void r128_freelist_reset( drm_device_t *dev );
 extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
 
 extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
-extern void r128_update_ring_snapshot( drm_r128_private_t *dev_priv );
+
+static inline void
+r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring )
+{
+       ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32);
+       if ( ring->space <= 0 )
+               ring->space += ring->size;
+}
+
+extern int r128_do_cce_idle( drm_r128_private_t *dev_priv );
+extern int r128_do_cleanup_cce( drm_device_t *dev );
+extern int r128_do_cleanup_pageflip( drm_device_t *dev );
 
                                /* r128_state.c */
 extern int r128_cce_clear( struct inode *inode, struct file *filp,
@@ -154,31 +164,8 @@ extern int r128_cce_depth( struct inode *inode, struct file *filp,
                           unsigned int cmd, unsigned long arg );
 extern int r128_cce_stipple( struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg );
-
-                               /* r128_bufs.c */
-extern int r128_addbufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int r128_mapbufs(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-
-                               /* r128_context.c */
-extern int  r128_resctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  r128_addctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  r128_modctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  r128_getctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  r128_switchctx(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
-extern int  r128_newctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  r128_rmctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-
-extern int  r128_context_switch(drm_device_t *dev, int old, int new);
-extern int  r128_context_switch_complete(drm_device_t *dev, int new);
+extern int r128_cce_indirect( struct inode *inode, struct file *filp,
+                             unsigned int cmd, unsigned long arg );
 
 
 /* Register definitions, register access macros and drmAddMap constants
@@ -215,8 +202,10 @@ extern int  r128_context_switch_complete(drm_device_t *dev, int new);
 #define R128_CLOCK_CNTL_INDEX          0x0008
 #define R128_CLOCK_CNTL_DATA           0x000c
 #      define R128_PLL_WR_EN                   (1 << 7)
-
 #define R128_CONSTANT_COLOR_C          0x1d34
+#define R128_CRTC_OFFSET               0x0224
+#define R128_CRTC_OFFSET_CNTL          0x0228
+#      define R128_CRTC_OFFSET_FLIP_CNTL       (1 << 16)
 
 #define R128_DP_GUI_MASTER_CNTL                0x146c
 #       define R128_GMC_SRC_PITCH_OFFSET_CNTL  (1    <<  0)
@@ -265,6 +254,7 @@ extern int  r128_context_switch_complete(drm_device_t *dev, int new);
 #      define R128_PC_FLUSH_ALL                0x00ff
 #      define R128_PC_BUSY                     (1 << 31)
 
+#define R128_PCI_GART_PAGE             0x017c
 #define R128_PRIM_TEX_CNTL_C           0x1cb0
 
 #define R128_SCALE_3D_CNTL             0x1a00
@@ -276,6 +266,8 @@ extern int  r128_context_switch_complete(drm_device_t *dev, int new);
 #define R128_TEX_CNTL_C                        0x1c9c
 #      define R128_TEX_CACHE_FLUSH             (1 << 23)
 
+#define R128_WAIT_UNTIL                        0x1720
+#      define R128_EVENT_CRTC_OFFSET           (1 << 0)
 #define R128_WINDOW_XY_OFFSET          0x1bcc
 
 
@@ -376,39 +368,69 @@ extern int  r128_context_switch_complete(drm_device_t *dev, int new);
 #define R128_WATERMARK_N               8
 #define R128_WATERMARK_K               128
 
-#define R128_MAX_USEC_TIMEOUT  100000  /* 100 ms */
+#define R128_MAX_USEC_TIMEOUT          100000  /* 100 ms */
 
 #define R128_LAST_FRAME_REG            R128_GUI_SCRATCH_REG0
 #define R128_LAST_DISPATCH_REG         R128_GUI_SCRATCH_REG1
-#define R128_MAX_VB_AGE                        0xffffffff
-
+#define R128_MAX_VB_AGE                        0x7fffffff
 #define R128_MAX_VB_VERTS              (0xffff)
 
+#define R128_RING_HIGH_MARK            128
 
-#define R128_BASE(reg)         ((unsigned long)(dev_priv->mmio->handle))
-#define R128_ADDR(reg)         (R128_BASE(reg) + reg)
+#define R128_PERFORMANCE_BOXES         0
 
-#define R128_READ(reg)         readl(R128_ADDR(reg))
-#define R128_WRITE(reg,val)    writel(val,R128_ADDR(reg))
 
-#define R128_READ8(reg)                readb(R128_ADDR(reg))
-#define R128_WRITE8(reg,val)   writeb(val,R128_ADDR(reg))
-
-#define R128_WRITE_PLL(addr,val)                                              \
-do {                                                                          \
-       R128_WRITE8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \
-       R128_WRITE(R128_CLOCK_CNTL_DATA, (val));                              \
+#define R128_BASE(reg)         ((unsigned long)(dev_priv->mmio->handle))
+#define R128_ADDR(reg)         (R128_BASE( reg ) + reg)
+
+#define R128_DEREF(reg)                *(volatile u32 *)R128_ADDR( reg )
+#ifdef __alpha__
+#define R128_READ(reg)         (_R128_READ((u32 *)R128_ADDR(reg)))
+static inline u32 _R128_READ(u32 *addr)
+{
+       mb();
+       return *(volatile u32 *)addr;
+}
+#define R128_WRITE(reg,val)                                            \
+do {                                                                   \
+       wmb();                                                          \
+       R128_DEREF(reg) = val;                                          \
+} while (0)
+#else
+#define R128_READ(reg)         le32_to_cpu( R128_DEREF( reg ) )
+#define R128_WRITE(reg,val)                                            \
+do {                                                                   \
+       R128_DEREF( reg ) = cpu_to_le32( val );                         \
+} while (0)
+#endif
+
+#define R128_DEREF8(reg)       *(volatile u8 *)R128_ADDR( reg )
+#ifdef __alpha__
+#define R128_READ8(reg)                _R128_READ8((u8 *)R128_ADDR(reg))
+static inline u8 _R128_READ8(u8 *addr)
+{
+       mb();
+       return *(volatile u8 *)addr;
+}
+#define R128_WRITE8(reg,val)                                           \
+do {                                                                   \
+       wmb();                                                          \
+       R128_DEREF8(reg) = val;                                         \
+} while (0)
+#else
+#define R128_READ8(reg)                R128_DEREF8( reg )
+#define R128_WRITE8(reg,val)   do { R128_DEREF8( reg ) = val; } while (0)
+#endif
+
+#define R128_WRITE_PLL(addr,val)                                       \
+do {                                                                   \
+       R128_WRITE8(R128_CLOCK_CNTL_INDEX,                              \
+                   ((addr) & 0x1f) | R128_PLL_WR_EN);                  \
+       R128_WRITE(R128_CLOCK_CNTL_DATA, (val));                        \
 } while (0)
 
 extern int R128_READ_PLL(drm_device_t *dev, int addr);
 
-#define R128CCE0(p,r,n)   ((p) | ((n) << 16) | ((r) >> 2))
-#define R128CCE1(p,r1,r2) ((p) | (((r2) >> 2) << 11) | ((r1) >> 2))
-#define R128CCE2(p)       ((p))
-#define R128CCE3(p,n)     ((p) | ((n) << 16))
-
-
-
 
 #define CCE_PACKET0( reg, n )          (R128_CCE_PACKET0 |             \
                                         ((n) << 16) | ((reg) >> 2))
@@ -419,33 +441,92 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
                                         (pkt) | ((n) << 16))
 
 
-#define r128_flush_write_combine()             mb()
+/* ================================================================
+ * Misc helper macros
+ */
+
+#define LOCK_TEST_WITH_RETURN( dev )                                   \
+do {                                                                   \
+       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||           \
+            dev->lock.pid != current->pid ) {                          \
+               DRM_ERROR( "%s called without lock held\n",             \
+                          __FUNCTION__ );                              \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+#define RING_SPACE_TEST_WITH_RETURN( dev_priv )                                \
+do {                                                                   \
+       drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i;          \
+       if ( ring->space < ring->high_mark ) {                          \
+               for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {      \
+                       r128_update_ring_snapshot( ring );              \
+                       if ( ring->space >= ring->high_mark )           \
+                               goto __ring_space_done;                 \
+                       udelay( 1 );                                    \
+               }                                                       \
+               DRM_ERROR( "ring space check failed!\n" );              \
+               return -EBUSY;                                          \
+       }                                                               \
+ __ring_space_done:                                                    \
+} while (0)
+
+#define VB_AGE_TEST_WITH_RETURN( dev_priv )                            \
+do {                                                                   \
+       drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;            \
+       if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) {           \
+               int __ret = r128_do_cce_idle( dev_priv );               \
+               if ( __ret < 0 ) return __ret;                          \
+               sarea_priv->last_dispatch = 0;                          \
+               r128_freelist_reset( dev );                             \
+       }                                                               \
+} while (0)
+
+#define R128_WAIT_UNTIL_PAGE_FLIPPED() do {                            \
+       OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) );                  \
+       OUT_RING( R128_EVENT_CRTC_OFFSET );                             \
+} while (0)
+
+
+/* ================================================================
+ * Ring control
+ */
+
+#define r128_flush_write_combine()     mb()
 
 
 #define R128_VERBOSE   0
 
-#define RING_LOCALS    int write; unsigned int tail_mask; volatile u32 *ring;
+#define RING_LOCALS                                                    \
+       int write; unsigned int tail_mask; volatile u32 *ring;
 
 #define BEGIN_RING( n ) do {                                           \
        if ( R128_VERBOSE ) {                                           \
                DRM_INFO( "BEGIN_RING( %d ) in %s\n",                   \
-                          n, __FUNCTION__ );                           \
+                          (n), __FUNCTION__ );                         \
        }                                                               \
-       if ( dev_priv->ring.space < n * sizeof(u32) ) {                 \
-               r128_wait_ring( dev_priv, n * sizeof(u32) );            \
+       if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {              \
+               r128_wait_ring( dev_priv, (n) * sizeof(u32) );          \
        }                                                               \
-       dev_priv->ring.space -= n * sizeof(u32);                        \
+       dev_priv->ring.space -= (n) * sizeof(u32);                      \
        ring = dev_priv->ring.start;                                    \
        write = dev_priv->ring.tail;                                    \
        tail_mask = dev_priv->ring.tail_mask;                           \
 } while (0)
 
+/* You can set this to zero if you want.  If the card locks up, you'll
+ * need to keep this set.  It works around a bug in early revs of the
+ * Rage 128 chipset, where the CCE would read 32 dwords past the end of
+ * the ring buffer before wrapping around.
+ */
+#define R128_BROKEN_CCE        1
+
 #define ADVANCE_RING() do {                                            \
        if ( R128_VERBOSE ) {                                           \
-               DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n",     \
+               DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
                          write, dev_priv->ring.tail );                 \
        }                                                               \
-       if ( write < 32 ) {                                             \
+       if ( R128_BROKEN_CCE && write < 32 ) {                          \
                memcpy( dev_priv->ring.end,                             \
                        dev_priv->ring.start,                           \
                        write * sizeof(u32) );                          \
@@ -460,10 +541,8 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
                DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",            \
                           (unsigned int)(x), write );                  \
        }                                                               \
-       ring[write++] = x;                                              \
+       ring[write++] = cpu_to_le32( x );                               \
        write &= tail_mask;                                             \
 } while (0)
 
-#define R128_PERFORMANCE_BOXES 0
-
 #endif /* __R128_DRV_H__ */
index 3f52c14b3d5800afc4ef2798dfb224b52b14c5a4..66af5c45686a116e7a4620d32fc6150487da46a8 100644 (file)
  *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
- *
  */
 
 #define __NO_VERSION__
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
 #include "drm.h"
+#include <linux/delay.h>
 
 
 /* ================================================================
@@ -181,14 +182,14 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
        RING_LOCALS;
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
 
-       BEGIN_RING( 7 + R128_TEX_MAXLEVELS );
+       BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
 
        OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C,
-                              2 + R128_TEX_MAXLEVELS ) );
+                              2 + R128_MAX_TEXTURE_LEVELS ) );
        OUT_RING( tex->tex_cntl );
        OUT_RING( tex->tex_combine_cntl );
        OUT_RING( ctx->tex_size_pitch_c );
-       for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
+       for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
                OUT_RING( tex->tex_offset[i] );
        }
 
@@ -207,13 +208,13 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
        RING_LOCALS;
        DRM_DEBUG( "    %s\n", __FUNCTION__ );
 
-       BEGIN_RING( 5 + R128_TEX_MAXLEVELS );
+       BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
 
        OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C,
-                              1 + R128_TEX_MAXLEVELS ) );
+                              1 + R128_MAX_TEXTURE_LEVELS ) );
        OUT_RING( tex->tex_cntl );
        OUT_RING( tex->tex_combine_cntl );
-       for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) {
+       for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
                OUT_RING( tex->tex_offset[i] );
        }
 
@@ -310,13 +311,13 @@ static void r128_clear_box( drm_r128_private_t *dev_priv,
        BEGIN_RING( 6 );
 
        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                 | R128_GMC_BRUSH_SOLID_COLOR
-                 | fb_bpp
-                 | R128_GMC_SRC_DATATYPE_COLOR
-                 | R128_ROP3_P
-                 | R128_GMC_CLR_CMP_CNTL_DIS
-                 R128_GMC_AUX_CLIP_DIS );
+       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                 R128_GMC_BRUSH_SOLID_COLOR |
+                 fb_bpp |
+                 R128_GMC_SRC_DATATYPE_COLOR |
+                 R128_ROP3_P |
+                 R128_GMC_CLR_CMP_CNTL_DIS |
+                 R128_GMC_AUX_CLIP_DIS );
 
        OUT_RING( (pitch << 21) | (offset >> 5) );
        OUT_RING( color );
@@ -360,42 +361,23 @@ static void r128_print_dirty( const char *msg, unsigned int flags )
 }
 
 static void r128_cce_dispatch_clear( drm_device_t *dev,
-                                    unsigned int flags,
-                                    int cx, int cy, int cw, int ch,
-                                    unsigned int clear_color,
-                                    unsigned int clear_depth )
+                                    drm_r128_clear_t *clear )
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        int nbox = sarea_priv->nbox;
        drm_clip_rect_t *pbox = sarea_priv->boxes;
-       u32 fb_bpp, depth_bpp;
+       unsigned int flags = clear->flags;
        int i;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
+       if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
+               unsigned int tmp = flags;
 
-       switch ( dev_priv->fb_bpp ) {
-       case 16:
-               fb_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 32:
-               fb_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return;
-       }
-       switch ( dev_priv->depth_bpp ) {
-       case 16:
-               depth_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 24:
-       case 32:
-               depth_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return;
+               flags &= ~(R128_FRONT | R128_BACK);
+               if ( tmp & R128_FRONT ) flags |= R128_BACK;
+               if ( tmp & R128_BACK )  flags |= R128_FRONT;
        }
 
        for ( i = 0 ; i < nbox ; i++ ) {
@@ -412,7 +394,7 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
                        BEGIN_RING( 2 );
 
                        OUT_RING( CCE_PACKET0( R128_DP_WRITE_MASK, 0 ) );
-                       OUT_RING( sarea_priv->context_state.plane_3d_mask_c );
+                       OUT_RING( clear->color_mask );
 
                        ADVANCE_RING();
                }
@@ -421,16 +403,16 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
                        BEGIN_RING( 6 );
 
                        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                 | R128_GMC_BRUSH_SOLID_COLOR
-                                 | fb_bpp
-                                 | R128_GMC_SRC_DATATYPE_COLOR
-                                 | R128_ROP3_P
-                                 | R128_GMC_CLR_CMP_CNTL_DIS
-                                 R128_GMC_AUX_CLIP_DIS );
+                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                 R128_GMC_BRUSH_SOLID_COLOR |
+                                 (dev_priv->color_fmt << 8) |
+                                 R128_GMC_SRC_DATATYPE_COLOR |
+                                 R128_ROP3_P |
+                                 R128_GMC_CLR_CMP_CNTL_DIS |
+                                 R128_GMC_AUX_CLIP_DIS );
 
                        OUT_RING( dev_priv->front_pitch_offset_c );
-                       OUT_RING( clear_color );
+                       OUT_RING( clear->clear_color );
 
                        OUT_RING( (x << 16) | y );
                        OUT_RING( (w << 16) | h );
@@ -442,16 +424,16 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
                        BEGIN_RING( 6 );
 
                        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                 | R128_GMC_BRUSH_SOLID_COLOR
-                                 | fb_bpp
-                                 | R128_GMC_SRC_DATATYPE_COLOR
-                                 | R128_ROP3_P
-                                 | R128_GMC_CLR_CMP_CNTL_DIS
-                                 R128_GMC_AUX_CLIP_DIS );
+                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                 R128_GMC_BRUSH_SOLID_COLOR |
+                                 (dev_priv->color_fmt << 8) |
+                                 R128_GMC_SRC_DATATYPE_COLOR |
+                                 R128_ROP3_P |
+                                 R128_GMC_CLR_CMP_CNTL_DIS |
+                                 R128_GMC_AUX_CLIP_DIS );
 
                        OUT_RING( dev_priv->back_pitch_offset_c );
-                       OUT_RING( clear_color );
+                       OUT_RING( clear->clear_color );
 
                        OUT_RING( (x << 16) | y );
                        OUT_RING( (w << 16) | h );
@@ -463,17 +445,17 @@ static void r128_cce_dispatch_clear( drm_device_t *dev,
                        BEGIN_RING( 6 );
 
                        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                 | R128_GMC_BRUSH_SOLID_COLOR
-                                 | depth_bpp
-                                 | R128_GMC_SRC_DATATYPE_COLOR
-                                 | R128_ROP3_P
-                                 | R128_GMC_CLR_CMP_CNTL_DIS
-                                 | R128_GMC_AUX_CLIP_DIS
-                                 R128_GMC_WR_MSK_DIS );
+                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                 R128_GMC_BRUSH_SOLID_COLOR |
+                                 (dev_priv->depth_fmt << 8) |
+                                 R128_GMC_SRC_DATATYPE_COLOR |
+                                 R128_ROP3_P |
+                                 R128_GMC_CLR_CMP_CNTL_DIS |
+                                 R128_GMC_AUX_CLIP_DIS |
+                                 R128_GMC_WR_MSK_DIS );
 
                        OUT_RING( dev_priv->depth_pitch_offset_c );
-                       OUT_RING( clear_depth );
+                       OUT_RING( clear->clear_depth );
 
                        OUT_RING( (x << 16) | y );
                        OUT_RING( (w << 16) | h );
@@ -489,29 +471,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        int nbox = sarea_priv->nbox;
        drm_clip_rect_t *pbox = sarea_priv->boxes;
-       u32 fb_bpp;
        int i;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
 #if R128_PERFORMANCE_BOXES
        /* Do some trivial performance monitoring...
         */
        r128_cce_performance_boxes( dev_priv );
 #endif
 
-       switch ( dev_priv->fb_bpp ) {
-       case 16:
-               fb_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 32:
-       default:
-               fb_bpp = R128_GMC_DST_32BPP;
-               break;
-       }
-
        for ( i = 0 ; i < nbox ; i++ ) {
                int x = pbox[i].x1;
                int y = pbox[i].y1;
@@ -521,16 +490,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
                BEGIN_RING( 7 );
 
                OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-               OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-                         | R128_GMC_DST_PITCH_OFFSET_CNTL
-                         | R128_GMC_BRUSH_NONE
-                         | fb_bpp
-                         | R128_GMC_SRC_DATATYPE_COLOR
-                         | R128_ROP3_S
-                         | R128_DP_SRC_SOURCE_MEMORY
-                         | R128_GMC_CLR_CMP_CNTL_DIS
-                         | R128_GMC_AUX_CLIP_DIS
-                         R128_GMC_WR_MSK_DIS );
+               OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+                         R128_GMC_DST_PITCH_OFFSET_CNTL |
+                         R128_GMC_BRUSH_NONE |
+                         (dev_priv->color_fmt << 8) |
+                         R128_GMC_SRC_DATATYPE_COLOR |
+                         R128_ROP3_S |
+                         R128_DP_SRC_SOURCE_MEMORY |
+                         R128_GMC_CLR_CMP_CNTL_DIS |
+                         R128_GMC_AUX_CLIP_DIS |
+                         R128_GMC_WR_MSK_DIS );
 
                OUT_RING( dev_priv->back_pitch_offset_c );
                OUT_RING( dev_priv->front_pitch_offset_c );
@@ -556,6 +525,47 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
        ADVANCE_RING();
 }
 
+static void r128_cce_dispatch_flip( drm_device_t *dev )
+{
+       drm_r128_private_t *dev_priv = dev->dev_private;
+       RING_LOCALS;
+       DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
+
+#if R128_PERFORMANCE_BOXES
+       /* Do some trivial performance monitoring...
+        */
+       r128_cce_performance_boxes( dev_priv );
+#endif
+
+       BEGIN_RING( 4 );
+
+       R128_WAIT_UNTIL_PAGE_FLIPPED();
+       OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) );
+
+       if ( dev_priv->current_page == 0 ) {
+               OUT_RING( dev_priv->back_offset );
+               dev_priv->current_page = 1;
+       } else {
+               OUT_RING( dev_priv->front_offset );
+               dev_priv->current_page = 0;
+       }
+
+       ADVANCE_RING();
+
+       /* Increment the frame counter.  The client-side 3D driver must
+        * throttle the framerate by waiting for this value before
+        * performing the swapbuffer ioctl.
+        */
+       dev_priv->sarea_priv->last_frame++;
+
+       BEGIN_RING( 2 );
+
+       OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) );
+       OUT_RING( dev_priv->sarea_priv->last_frame );
+
+       ADVANCE_RING();
+}
+
 static void r128_cce_dispatch_vertex( drm_device_t *dev,
                                      drm_buf_t *buf )
 {
@@ -563,7 +573,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
        drm_r128_buf_priv_t *buf_priv = buf->dev_private;
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        int format = sarea_priv->vc_format;
-       int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
+       int offset = buf->bus_address;
        int size = buf->used;
        int prim = buf_priv->prim;
        int i = 0;
@@ -571,8 +581,6 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
        DRM_DEBUG( "%s: buf=%d nbox=%d\n",
                   __FUNCTION__, buf->idx, sarea_priv->nbox );
 
-       r128_update_ring_snapshot( dev_priv );
-
        if ( 0 )
                r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
 
@@ -626,22 +634,10 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
 
        dev_priv->sarea_priv->last_dispatch++;
 
-#if 0
-       if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-               ret = r128_do_cce_idle( dev_priv );
-               if ( ret < 0 ) return ret;
-               dev_priv->submit_age = 0;
-               r128_freelist_reset( dev );
-       }
-#endif
-
        sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
        sarea_priv->nbox = 0;
 }
 
-
-
-
 static void r128_cce_dispatch_indirect( drm_device_t *dev,
                                        drm_buf_t *buf,
                                        int start, int end )
@@ -652,11 +648,8 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
        DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
                   buf->idx, start, end );
 
-       r128_update_ring_snapshot( dev_priv );
-
        if ( start != end ) {
-               int offset = (dev_priv->buffers->offset - dev->agp->base
-                             + buf->offset + start);
+               int offset = buf->bus_address + start;
                int dwords = (end - start + 3) / sizeof(u32);
 
                /* Indirect buffer data must be an even number of
@@ -667,7 +660,7 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
                        u32 *data = (u32 *)
                                ((char *)dev_priv->buffers->handle
                                 + buf->offset + start);
-                       data[dwords++] = R128_CCE_PACKET2;
+                       data[dwords++] = cpu_to_le32( R128_CCE_PACKET2 );
                }
 
                buf_priv->dispatched = 1;
@@ -700,15 +693,6 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
        }
 
        dev_priv->sarea_priv->last_dispatch++;
-
-#if 0
-       if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-               ret = r128_do_cce_idle( dev_priv );
-               if ( ret < 0 ) return ret;
-               dev_priv->submit_age = 0;
-               r128_freelist_reset( dev );
-       }
-#endif
 }
 
 static void r128_cce_dispatch_indices( drm_device_t *dev,
@@ -720,7 +704,7 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
        drm_r128_buf_priv_t *buf_priv = buf->dev_private;
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        int format = sarea_priv->vc_format;
-       int offset = dev_priv->buffers->offset - dev->agp->base;
+       int offset = dev_priv->buffers->offset - dev_priv->cce_buffers_offset;
        int prim = buf_priv->prim;
        u32 *data;
        int dwords;
@@ -728,8 +712,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
        RING_LOCALS;
        DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
 
-       r128_update_ring_snapshot( dev_priv );
-
        if ( 0 )
                r128_print_dirty( "dispatch_indices", sarea_priv->dirty );
 
@@ -745,16 +727,21 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
                data = (u32 *)((char *)dev_priv->buffers->handle
                               + buf->offset + start);
 
-               data[0] = CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+               data[0] = cpu_to_le32( CCE_PACKET3( R128_3D_RNDR_GEN_INDX_PRIM,
+                                                   dwords-2 ) );
 
-               data[1] = offset;
-               data[2] = R128_MAX_VB_VERTS;
-               data[3] = format;
-               data[4] = (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
-                          (count << 16));
+               data[1] = cpu_to_le32( offset );
+               data[2] = cpu_to_le32( R128_MAX_VB_VERTS );
+               data[3] = cpu_to_le32( format );
+               data[4] = cpu_to_le32( (prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
+                                       (count << 16)) );
 
                if ( count & 0x1 ) {
+#ifdef __LITTLE_ENDIAN
                        data[dwords-1] &= 0x0000ffff;
+#else
+                       data[dwords-1] &= 0xffff0000;
+#endif
                }
 
                do {
@@ -789,15 +776,6 @@ static void r128_cce_dispatch_indices( drm_device_t *dev,
 
        dev_priv->sarea_priv->last_dispatch++;
 
-#if 0
-       if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
-               ret = r128_do_cce_idle( dev_priv );
-               if ( ret < 0 ) return ret;
-               dev_priv->submit_age = 0;
-               r128_freelist_reset( dev );
-       }
-#endif
-
        sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
        sarea_priv->nbox = 0;
 }
@@ -814,20 +792,22 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
        /* The compiler won't optimize away a division by a variable,
         * even if the only legal values are powers of two.  Thus, we'll
         * use a shift instead.
         */
        switch ( blit->format ) {
+       case R128_DATATYPE_ARGB8888:
+               dword_shift = 0;
+               break;
        case R128_DATATYPE_ARGB1555:
        case R128_DATATYPE_RGB565:
        case R128_DATATYPE_ARGB4444:
                dword_shift = 1;
                break;
-       case R128_DATATYPE_ARGB8888:
-               dword_shift = 0;
+       case R128_DATATYPE_CI8:
+       case R128_DATATYPE_RGB8:
+               dword_shift = 2;
                break;
        default:
                DRM_ERROR( "invalid blit format %d\n", blit->format );
@@ -867,23 +847,23 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
 
        data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
 
-       data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 );
-       data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL
-                   | R128_GMC_BRUSH_NONE
-                   | (blit->format << 8)
-                   | R128_GMC_SRC_DATATYPE_COLOR
-                   | R128_ROP3_S
-                   | R128_DP_SRC_SOURCE_HOST_DATA
-                   | R128_GMC_CLR_CMP_CNTL_DIS
-                   | R128_GMC_AUX_CLIP_DIS
-                   | R128_GMC_WR_MSK_DIS );
-
-       data[2] = (blit->pitch << 21) | (blit->offset >> 5);
-       data[3] = 0xffffffff;
-       data[4] = 0xffffffff;
-       data[5] = (blit->y << 16) | blit->x;
-       data[6] = (blit->height << 16) | blit->width;
-       data[7] = dwords;
+       data[0] = cpu_to_le32( CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ) );
+       data[1] = cpu_to_le32( (R128_GMC_DST_PITCH_OFFSET_CNTL |
+                               R128_GMC_BRUSH_NONE |
+                               (blit->format << 8) |
+                               R128_GMC_SRC_DATATYPE_COLOR |
+                               R128_ROP3_S |
+                               R128_DP_SRC_SOURCE_HOST_DATA |
+                               R128_GMC_CLR_CMP_CNTL_DIS |
+                               R128_GMC_AUX_CLIP_DIS |
+                               R128_GMC_WR_MSK_DIS) );
+
+       data[2] = cpu_to_le32( (blit->pitch << 21) | (blit->offset >> 5) );
+       data[3] = cpu_to_le32( 0xffffffff );
+       data[4] = cpu_to_le32( 0xffffffff );
+       data[5] = cpu_to_le32( (blit->y << 16) | blit->x );
+       data[6] = cpu_to_le32( (blit->height << 16) | blit->width );
+       data[7] = cpu_to_le32( dwords );
 
        buf->used = (dwords + 8) * sizeof(u32);
 
@@ -918,25 +898,10 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
        int count, x, y;
        u32 *buffer;
        u8 *mask;
-       u32 depth_bpp;
        int i;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
-       switch ( dev_priv->depth_bpp ) {
-       case 16:
-               depth_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 24:
-       case 32:
-               depth_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        count = depth->n;
        if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
                return -EFAULT;
@@ -945,7 +910,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
                return -EFAULT;
        }
 
-       buffer = kmalloc( depth->n * sizeof(u32), 0 );
+       buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
        if ( buffer == NULL )
                return -ENOMEM;
        if ( copy_from_user( buffer, depth->buffer,
@@ -955,7 +920,7 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
        }
 
        if ( depth->mask ) {
-               mask = kmalloc( depth->n * sizeof(u8), 0 );
+               mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
                if ( mask == NULL ) {
                        kfree( buffer );
                        return -ENOMEM;
@@ -971,15 +936,14 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
                        if ( mask[i] ) {
                                BEGIN_RING( 6 );
 
-                               OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
-                                                      4 ) );
-                               OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                         | R128_GMC_BRUSH_SOLID_COLOR
-                                         | depth_bpp
-                                         | R128_GMC_SRC_DATATYPE_COLOR
-                                         | R128_ROP3_P
-                                         | R128_GMC_CLR_CMP_CNTL_DIS
-                                         | R128_GMC_WR_MSK_DIS );
+                               OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+                               OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                         R128_GMC_BRUSH_SOLID_COLOR |
+                                         (dev_priv->depth_fmt << 8) |
+                                         R128_GMC_SRC_DATATYPE_COLOR |
+                                         R128_ROP3_P |
+                                         R128_GMC_CLR_CMP_CNTL_DIS |
+                                         R128_GMC_WR_MSK_DIS );
 
                                OUT_RING( dev_priv->depth_pitch_offset_c );
                                OUT_RING( buffer[i] );
@@ -997,13 +961,13 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev,
                        BEGIN_RING( 6 );
 
                        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                 | R128_GMC_BRUSH_SOLID_COLOR
-                                 | depth_bpp
-                                 | R128_GMC_SRC_DATATYPE_COLOR
-                                 | R128_ROP3_P
-                                 | R128_GMC_CLR_CMP_CNTL_DIS
-                                 R128_GMC_WR_MSK_DIS );
+                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                 R128_GMC_BRUSH_SOLID_COLOR |
+                                 (dev_priv->depth_fmt << 8) |
+                                 R128_GMC_SRC_DATATYPE_COLOR |
+                                 R128_ROP3_P |
+                                 R128_GMC_CLR_CMP_CNTL_DIS |
+                                 R128_GMC_WR_MSK_DIS );
 
                        OUT_RING( dev_priv->depth_pitch_offset_c );
                        OUT_RING( buffer[i] );
@@ -1027,32 +991,17 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
        int count, *x, *y;
        u32 *buffer;
        u8 *mask;
-       u32 depth_bpp;
        int i;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
-       switch ( dev_priv->depth_bpp ) {
-       case 16:
-               depth_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 24:
-       case 32:
-               depth_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        count = depth->n;
 
-       x = kmalloc( count * sizeof(*x), 0 );
+       x = kmalloc( count * sizeof(*x), GFP_KERNEL );
        if ( x == NULL ) {
                return -ENOMEM;
        }
-       y = kmalloc( count * sizeof(*y), 0 );
+       y = kmalloc( count * sizeof(*y), GFP_KERNEL );
        if ( y == NULL ) {
                kfree( x );
                return -ENOMEM;
@@ -1068,7 +1017,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
                return -EFAULT;
        }
 
-       buffer = kmalloc( depth->n * sizeof(u32), 0 );
+       buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
        if ( buffer == NULL ) {
                kfree( x );
                kfree( y );
@@ -1083,7 +1032,7 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
        }
 
        if ( depth->mask ) {
-               mask = kmalloc( depth->n * sizeof(u8), 0 );
+               mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
                if ( mask == NULL ) {
                        kfree( x );
                        kfree( y );
@@ -1103,15 +1052,14 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
                        if ( mask[i] ) {
                                BEGIN_RING( 6 );
 
-                               OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
-                                                      4 ) );
-                               OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                         | R128_GMC_BRUSH_SOLID_COLOR
-                                         | depth_bpp
-                                         | R128_GMC_SRC_DATATYPE_COLOR
-                                         | R128_ROP3_P
-                                         | R128_GMC_CLR_CMP_CNTL_DIS
-                                         | R128_GMC_WR_MSK_DIS );
+                               OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
+                               OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                         R128_GMC_BRUSH_SOLID_COLOR |
+                                         (dev_priv->depth_fmt << 8) |
+                                         R128_GMC_SRC_DATATYPE_COLOR |
+                                         R128_ROP3_P |
+                                         R128_GMC_CLR_CMP_CNTL_DIS |
+                                         R128_GMC_WR_MSK_DIS );
 
                                OUT_RING( dev_priv->depth_pitch_offset_c );
                                OUT_RING( buffer[i] );
@@ -1129,13 +1077,13 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
                        BEGIN_RING( 6 );
 
                        OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
-                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
-                                 | R128_GMC_BRUSH_SOLID_COLOR
-                                 | depth_bpp
-                                 | R128_GMC_SRC_DATATYPE_COLOR
-                                 | R128_ROP3_P
-                                 | R128_GMC_CLR_CMP_CNTL_DIS
-                                 R128_GMC_WR_MSK_DIS );
+                       OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL |
+                                 R128_GMC_BRUSH_SOLID_COLOR |
+                                 (dev_priv->depth_fmt << 8) |
+                                 R128_GMC_SRC_DATATYPE_COLOR |
+                                 R128_ROP3_P |
+                                 R128_GMC_CLR_CMP_CNTL_DIS |
+                                 R128_GMC_WR_MSK_DIS );
 
                        OUT_RING( dev_priv->depth_pitch_offset_c );
                        OUT_RING( buffer[i] );
@@ -1159,24 +1107,9 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev,
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, x, y;
-       u32 depth_bpp;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
-       switch ( dev_priv->depth_bpp ) {
-       case 16:
-               depth_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 24:
-       case 32:
-               depth_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        count = depth->n;
        if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
                return -EFAULT;
@@ -1188,15 +1121,15 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev,
        BEGIN_RING( 7 );
 
        OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-       OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-                 | R128_GMC_DST_PITCH_OFFSET_CNTL
-                 | R128_GMC_BRUSH_NONE
-                 | depth_bpp
-                 | R128_GMC_SRC_DATATYPE_COLOR
-                 | R128_ROP3_S
-                 | R128_DP_SRC_SOURCE_MEMORY
-                 | R128_GMC_CLR_CMP_CNTL_DIS
-                 R128_GMC_WR_MSK_DIS );
+       OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+                 R128_GMC_DST_PITCH_OFFSET_CNTL |
+                 R128_GMC_BRUSH_NONE |
+                 (dev_priv->depth_fmt << 8) |
+                 R128_GMC_SRC_DATATYPE_COLOR |
+                 R128_ROP3_S |
+                 R128_DP_SRC_SOURCE_MEMORY |
+                 R128_GMC_CLR_CMP_CNTL_DIS |
+                 R128_GMC_WR_MSK_DIS );
 
        OUT_RING( dev_priv->depth_pitch_offset_c );
        OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1215,35 +1148,20 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
 {
        drm_r128_private_t *dev_priv = dev->dev_private;
        int count, *x, *y;
-       u32 depth_bpp;
        int i;
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
-       switch ( dev_priv->depth_bpp ) {
-       case 16:
-               depth_bpp = R128_GMC_DST_16BPP;
-               break;
-       case 24:
-       case 32:
-               depth_bpp = R128_GMC_DST_32BPP;
-               break;
-       default:
-               return -EINVAL;
-       }
-
        count = depth->n;
        if ( count > dev_priv->depth_pitch ) {
                count = dev_priv->depth_pitch;
        }
 
-       x = kmalloc( count * sizeof(*x), 0 );
+       x = kmalloc( count * sizeof(*x), GFP_KERNEL );
        if ( x == NULL ) {
                return -ENOMEM;
        }
-       y = kmalloc( count * sizeof(*y), 0 );
+       y = kmalloc( count * sizeof(*y), GFP_KERNEL );
        if ( y == NULL ) {
                kfree( x );
                return -ENOMEM;
@@ -1263,15 +1181,15 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
                BEGIN_RING( 7 );
 
                OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
-               OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
-                         | R128_GMC_DST_PITCH_OFFSET_CNTL
-                         | R128_GMC_BRUSH_NONE
-                         | depth_bpp
-                         | R128_GMC_SRC_DATATYPE_COLOR
-                         | R128_ROP3_S
-                         | R128_DP_SRC_SOURCE_MEMORY
-                         | R128_GMC_CLR_CMP_CNTL_DIS
-                         R128_GMC_WR_MSK_DIS );
+               OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL |
+                         R128_GMC_DST_PITCH_OFFSET_CNTL |
+                         R128_GMC_BRUSH_NONE |
+                         (dev_priv->depth_fmt << 8) |
+                         R128_GMC_SRC_DATATYPE_COLOR |
+                         R128_ROP3_S |
+                         R128_DP_SRC_SOURCE_MEMORY |
+                         R128_GMC_CLR_CMP_CNTL_DIS |
+                         R128_GMC_WR_MSK_DIS );
 
                OUT_RING( dev_priv->depth_pitch_offset_c );
                OUT_RING( dev_priv->span_pitch_offset_c );
@@ -1301,11 +1219,9 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       r128_update_ring_snapshot( dev_priv );
-
        BEGIN_RING( 33 );
 
-       OUT_RING(  CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
+       OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
        for ( i = 0 ; i < 32 ; i++ ) {
                OUT_RING( stipple[i] );
        }
@@ -1328,22 +1244,18 @@ int r128_cce_clear( struct inode *inode, struct file *filp,
        drm_r128_clear_t clear;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "r128_cce_clear called without lock held\n" );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
                             sizeof(clear) ) )
                return -EFAULT;
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
        if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-       r128_cce_dispatch_clear( dev, clear.flags,
-                                clear.x, clear.y, clear.w, clear.h,
-                                clear.clear_color, clear.clear_depth );
+       r128_cce_dispatch_clear( dev, &clear );
 
        /* Make sure we restore the 3D state next time.
         */
@@ -1361,20 +1273,20 @@ int r128_cce_swap( struct inode *inode, struct file *filp,
        drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "r128_cce_swap called without lock held\n" );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
        if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
-       r128_cce_dispatch_swap( dev );
-
-       /* Make sure we restore the 3D state next time.
-        */
-       dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
+       if ( !dev_priv->page_flipping ) {
+               r128_cce_dispatch_swap( dev );
+               dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
+                                               R128_UPLOAD_MASKS);
+       } else {
+               r128_cce_dispatch_flip( dev );
+       }
 
        return 0;
 }
@@ -1390,13 +1302,10 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
        drm_r128_buf_priv_t *buf_priv;
        drm_r128_vertex_t vertex;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-       if ( !dev_priv || dev_priv->is_pci ) {
-               DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
                return -EINVAL;
        }
 
@@ -1419,6 +1328,9 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
+
        buf = dma->buflist[vertex.idx];
        buf_priv = buf->dev_private;
 
@@ -1453,13 +1365,10 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
        drm_r128_indices_t elts;
        int count;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-       if ( !dev_priv || dev_priv->is_pci ) {
-               DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
                return -EINVAL;
        }
 
@@ -1482,6 +1391,9 @@ int r128_cce_indices( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
+
        buf = dma->buflist[elts.idx];
        buf_priv = buf->dev_private;
 
@@ -1522,13 +1434,10 @@ int r128_cce_blit( struct inode *inode, struct file *filp,
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
        drm_device_dma_t *dma = dev->dma;
+       drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_blit_t blit;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &blit, (drm_r128_blit_t *)arg,
                             sizeof(blit) ) )
@@ -1543,6 +1452,9 @@ int r128_cce_blit( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
+
        return r128_cce_dispatch_blit( dev, &blit );
 }
 
@@ -1551,18 +1463,17 @@ int r128_cce_depth( struct inode *inode, struct file *filp,
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
+       drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_depth_t depth;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &depth, (drm_r128_depth_t *)arg,
                             sizeof(depth) ) )
                return -EFAULT;
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
        switch ( depth.func ) {
        case R128_WRITE_SPAN:
                return r128_cce_dispatch_write_span( dev, &depth );
@@ -1582,14 +1493,11 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
+       drm_r128_private_t *dev_priv = dev->dev_private;
        drm_r128_stipple_t stipple;
        u32 mask[32];
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg,
                             sizeof(stipple) ) )
@@ -1599,7 +1507,22 @@ int r128_cce_stipple( struct inode *inode, struct file *filp,
                             32 * sizeof(u32) ) )
                return -EFAULT;
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
        r128_cce_dispatch_stipple( dev, mask );
 
        return 0;
 }
+
+int r128_cce_indirect( struct inode *inode, struct file *filp,
+                      unsigned int cmd, unsigned long arg )
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->dev;
+
+       LOCK_TEST_WITH_RETURN( dev );
+
+       /* Indirect buffer firing is not supported at this time.
+        */
+       return -EINVAL;
+}
diff --git a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h
new file mode 100644 (file)
index 0000000..0fdeb82
--- /dev/null
@@ -0,0 +1,81 @@
+/* radeon.h -- ATI Radeon DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 17:07:34 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __RADEON_H__
+#define __RADEON_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) radeon_##x
+
+/* General customization:
+ */
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                0
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+#define __HAVE_SG              1
+#define __HAVE_PCI_DMA         1
+
+/* Driver customization:
+ */
+#define DRIVER_PRERELEASE() do {                                       \
+       if ( dev->dev_private ) {                                       \
+               drm_radeon_private_t *dev_priv = dev->dev_private;      \
+               if ( dev_priv->page_flipping ) {                        \
+                       radeon_do_cleanup_pageflip( dev );              \
+               }                                                       \
+       }                                                               \
+} while (0)
+
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) radeon_do_cleanup_cp( dev );            \
+} while (0)
+
+/* DMA customization:
+ */
+#define __HAVE_DMA             1
+
+#if 0
+/* GH: Remove this for now... */
+#define __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       drm_radeon_private_t *dev_priv = dev->dev_private;              \
+       return radeon_do_cp_idle( dev_priv );                           \
+} while (0)
+#endif
+
+/* Buffer customization:
+ */
+#define DRIVER_BUF_PRIV_T      drm_radeon_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_radeon_private_t *)((dev)->dev_private))->buffers
+
+#endif
diff --git a/drivers/char/drm/radeon_bufs.c b/drivers/char/drm/radeon_bufs.c
deleted file mode 100644 (file)
index 584fb81..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/* radeon_bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
- *
- * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Fremont, 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: Kevin E. Martin <martin@valinux.com>
- *          Rickard E. (Rik) Faith <faith@valinux.com>
- *         Jeff Hartmann <jhartmann@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include <linux/config.h>
-#include "drmP.h"
-#include "radeon_drv.h"
-#include "linux/un.h"
-
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-int radeon_addbufs_agp(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg)
-{
-       drm_file_t       *priv = filp->private_data;
-       drm_device_t     *dev  = priv->dev;
-       drm_device_dma_t *dma  = dev->dma;
-       drm_buf_desc_t    request;
-       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;
-
-       if (!dma) return -EINVAL;
-
-       if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
-               return -EFAULT;
-
-       count      = request.count;
-       order      = drm_order(request.size);
-       size       = 1 << order;
-
-       alignment  = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(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: %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 -EINVAL;
-       if (dev->queue_count) return -EBUSY; /* Not while in use */
-
-       spin_lock(&dev->count_lock);
-       if (dev->buf_use) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       atomic_inc(&dev->buf_alloc);
-       spin_unlock(&dev->count_lock);
-
-       down(&dev->struct_sem);
-       entry = &dma->bufs[order];
-       if (entry->buf_count) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM; /* May only call once for each order */
-       }
-
-       /* Might be too low a limit. XFree folks need to fix this properly */
-       
-       if(count < 0 || count > 4096)
-       {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -EINVAL;
-       }
-               
-       entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
-                                  DRM_MEM_BUFS);
-       if (!entry->buflist) {
-               up(&dev->struct_sem);
-               atomic_dec(&dev->buf_alloc);
-               return -ENOMEM;
-       }
-       memset(entry->buflist, 0, count * sizeof(*entry->buflist));
-
-       entry->buf_size   = size;
-       entry->page_order = page_order;
-       offset            = 0;
-
-       for (offset = 0;
-            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 + offset);
-               buf->address = (void *)(agp_offset + offset);
-               buf->next    = NULL;
-               buf->waiting = 0;
-               buf->pending = 0;
-               init_waitqueue_head(&buf->dma_wait);
-               buf->pid     = 0;
-
-               buf->dev_priv_size = sizeof(drm_radeon_buf_priv_t);
-               buf->dev_private   = drm_alloc(sizeof(drm_radeon_buf_priv_t),
-                                              DRM_MEM_BUFS);
-                if (!buf->dev_private) {
-                        up(&dev->struct_sem);
-                        atomic_dec(&dev->buf_alloc);
-                        return -ENOMEM;
-                }
-               memset(buf->dev_private, 0, buf->dev_priv_size);
-
-#if DRM_DMA_HISTOGRAM
-               buf->time_queued     = 0;
-               buf->time_dispatched = 0;
-               buf->time_completed  = 0;
-               buf->time_freed      = 0;
-#endif
-
-               byte_count += PAGE_SIZE << page_order;
-
-               DRM_DEBUG("buffer %d @ %p\n",
-                         entry->buf_count, buf->address);
-       }
-
-       DRM_DEBUG("byte_count: %d\n", byte_count);
-
-       dma->buflist = drm_realloc(dma->buflist,
-                                  dma->buf_count * sizeof(*dma->buflist),
-                                  (dma->buf_count + entry->buf_count)
-                                  * sizeof(*dma->buflist),
-                                  DRM_MEM_BUFS);
-       for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++)
-               dma->buflist[i] = &entry->buflist[i - dma->buf_count];
-
-       dma->buf_count  += entry->buf_count;
-       dma->byte_count += byte_count;
-
-       drm_freelist_create(&entry->freelist, entry->buf_count);
-       for (i = 0; i < entry->buf_count; i++) {
-               drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
-       }
-
-       up(&dev->struct_sem);
-
-       request.count = entry->buf_count;
-       request.size  = size;
-
-       if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request)))
-               return -EFAULT;
-
-       dma->flags = _DRM_DMA_USE_AGP;
-
-       atomic_dec(&dev->buf_alloc);
-       return 0;
-}
-#endif
-
-int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t              *priv           = filp->private_data;
-       drm_device_t            *dev            = priv->dev;
-       drm_radeon_private_t    *dev_priv       = dev->dev_private;
-       drm_buf_desc_t          request;
-
-       if (!dev_priv || dev_priv->is_pci) return -EINVAL;
-
-       if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
-               return -EFAULT;
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       if (request.flags & _DRM_AGP_BUFFER)
-               return radeon_addbufs_agp(inode, filp, cmd, arg);
-       else
-#endif
-               return -EINVAL;
-}
-
-int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t              *priv           = filp->private_data;
-       drm_device_t            *dev            = priv->dev;
-       drm_radeon_private_t    *dev_priv       = dev->dev_private;
-       drm_device_dma_t        *dma            = dev->dma;
-       int                      retcode        = 0;
-       const int                zero           = 0;
-       unsigned long            virtual;
-       unsigned long            address;
-       drm_buf_map_t            request;
-       int                      i;
-
-       if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL;
-
-       DRM_DEBUG("\n");
-
-       spin_lock(&dev->count_lock);
-       if (atomic_read(&dev->buf_alloc)) {
-               spin_unlock(&dev->count_lock);
-               return -EBUSY;
-       }
-       ++dev->buf_use;         /* Can't allocate more after this call */
-       spin_unlock(&dev->count_lock);
-
-       if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request)))
-               return -EFAULT;
-
-       if (request.count >= dma->buf_count) {
-               if (dma->flags & _DRM_DMA_USE_AGP) {
-                       drm_map_t *map;
-
-                       map = dev_priv->buffers;
-                       if (!map) {
-                               retcode = -EINVAL;
-                               goto done;
-                       }
-
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size,
-                                         PROT_READ|PROT_WRITE,
-                                         MAP_SHARED,
-                                         (unsigned long)map->offset);
-                       up_write(&current->mm->mmap_sem);
-               } else {
-                       down_write(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
-                                         PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-                       up_write(&current->mm->mmap_sem);
-               }
-               if (virtual > -1024UL) {
-                       /* Real error */
-                       retcode = (signed long)virtual;
-                       goto done;
-               }
-               request.virtual = (void *)virtual;
-
-               for (i = 0; i < dma->buf_count; i++) {
-                       if (copy_to_user(&request.list[i].idx,
-                                        &dma->buflist[i]->idx,
-                                        sizeof(request.list[0].idx))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].total,
-                                        &dma->buflist[i]->total,
-                                        sizeof(request.list[0].total))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       if (copy_to_user(&request.list[i].used,
-                                        &zero,
-                                        sizeof(zero))) {
-                               retcode = -EFAULT;
-                               goto done;
-                       }
-                       address = virtual + dma->buflist[i]->offset;
-                       if (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);
-
-       if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request)))
-               return -EFAULT;
-
-       return retcode;
-}
diff --git a/drivers/char/drm/radeon_context.c b/drivers/char/drm/radeon_context.c
deleted file mode 100644 (file)
index e428dc2..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* radeon_context.c -- IOCTLs for Radeon contexts -*- linux-c -*-
- *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Fremont, 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.
- *
- * Author: Kevin E. Martin <martin@valinux.com>
- *         Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "radeon_drv.h"
-
-extern drm_ctx_t radeon_res_ctx;
-
-static int radeon_alloc_queue(drm_device_t *dev)
-{
-       return drm_ctxbitmap_next(dev);
-}
-
-int radeon_context_switch(drm_device_t *dev, int old, int new)
-{
-        char        buf[64];
-
-        atomic_inc(&dev->total_ctx);
-
-        if (test_and_set_bit(0, &dev->context_flag)) {
-                DRM_ERROR("Reentering -- FIXME\n");
-                return -EBUSY;
-        }
-
-#if DRM_DMA_HISTOGRAM
-        dev->ctx_start = get_cycles();
-#endif
-
-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-        if (new == dev->last_context) {
-                clear_bit(0, &dev->context_flag);
-                return 0;
-        }
-
-        if (drm_flags & DRM_FLAG_NOCTX) {
-                radeon_context_switch_complete(dev, new);
-        } else {
-                sprintf(buf, "C %d %d\n", old, new);
-                drm_write_string(dev, buf);
-        }
-
-        return 0;
-}
-
-int radeon_context_switch_complete(drm_device_t *dev, int new)
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-
-        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. */
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                      - dev->ctx_start)]);
-
-#endif
-        clear_bit(0, &dev->context_flag);
-        wake_up(&dev->context_wait);
-
-        return 0;
-}
-
-
-int radeon_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i], &i, sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-
-int radeon_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = radeon_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Skip kernel's context and get a new one. */
-               ctx.handle = radeon_alloc_queue(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 (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int radeon_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       if (ctx.flags==_DRM_CONTEXT_PRESERVED)
-               radeon_res_ctx.handle=ctx.handle;
-       return 0;
-}
-
-int radeon_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       /* This is 0, because we don't hanlde any context flags */
-       ctx.flags = 0;
-       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int radeon_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                    unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return radeon_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int radeon_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       radeon_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int radeon_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       drm_ctxbitmap_free(dev, ctx.handle);
-
-       return 0;
-}
index 5d662bc085d56c0fd7578e8d7989c81c01b58829..a7127b2b584eafb1284fa570dae3a64593483c59 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Kevin E. Martin <martin@valinux.com>
- *   Gareth Hughes <gareth@valinux.com>
- *
+ *    Kevin E. Martin <martin@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
 
 
 #define RADEON_FIFO_DEBUG      0
 
+#if defined(__alpha__)
+# define PCIGART_ENABLED
+#else
+# undef PCIGART_ENABLED
+#endif
+
 
 /* CP microcode (from ATI) */
 static u32 radeon_cp_microcode[][2] = {
@@ -300,26 +306,6 @@ static u32 radeon_cp_microcode[][2] = {
 };
 
 
-#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
-
-#define DO_IOREMAPFREE(_m)                                             \
-       do {                                                            \
-               if ((_m)->handle && (_m)->size)                         \
-                       drm_ioremapfree((_m)->handle, (_m)->size);      \
-       } while (0)
-
-#define DO_FIND_MAP(_m, _o)                                            \
-       do {                                                            \
-               int _i;                                                 \
-               for (_i = 0; _i < dev->map_count; _i++) {               \
-                       if (dev->maplist[_i]->offset == _o) {           \
-                               _m = dev->maplist[_i];                  \
-                               break;                                  \
-                       }                                               \
-               }                                                       \
-       } while (0)
-
-
 int RADEON_READ_PLL(drm_device_t *dev, int addr)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -338,6 +324,16 @@ static void radeon_status( drm_radeon_private_t *dev_priv )
                (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) );
        printk( "CP_RB_WTPR = 0x%08x\n",
                (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) );
+       printk( "AIC_CNTL = 0x%08x\n",
+               (unsigned int)RADEON_READ( RADEON_AIC_CNTL ) );
+       printk( "AIC_STAT = 0x%08x\n",
+               (unsigned int)RADEON_READ( RADEON_AIC_STAT ) );
+       printk( "AIC_PT_BASE = 0x%08x\n",
+               (unsigned int)RADEON_READ( RADEON_AIC_PT_BASE ) );
+       printk( "TLB_ADDR = 0x%08x\n",
+               (unsigned int)RADEON_READ( RADEON_AIC_TLB_ADDR ) );
+       printk( "TLB_DATA = 0x%08x\n",
+               (unsigned int)RADEON_READ( RADEON_AIC_TLB_DATA ) );
 }
 #endif
 
@@ -421,6 +417,7 @@ static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
 static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
 {
        int i;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
        radeon_do_wait_for_idle( dev_priv );
 
@@ -439,6 +436,7 @@ static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
  */
 static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
 {
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 #if 0
        u32 tmp;
 
@@ -452,6 +450,7 @@ static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
 int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
 {
        RING_LOCALS;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
        BEGIN_RING( 6 );
 
@@ -469,6 +468,7 @@ int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
 static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
 {
        RING_LOCALS;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
        radeon_do_wait_for_idle( dev_priv );
 
@@ -492,6 +492,7 @@ static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
 static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
 {
        u32 cur_read_ptr;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
        cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
        RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
@@ -505,6 +506,8 @@ static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
  */
 static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
 {
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
        RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
 
        dev_priv->cp_running = 0;
@@ -523,8 +526,13 @@ static int radeon_do_engine_reset( drm_device_t *dev )
        clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX );
        mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL );
 
-       /* FIXME: remove magic number here and in radeon ddx driver!!! */
-       RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl | 0x003f00000 );
+       RADEON_WRITE_PLL( RADEON_MCLK_CNTL, ( mclk_cntl |
+                                             RADEON_FORCEON_MCLKA |
+                                             RADEON_FORCEON_MCLKB |
+                                             RADEON_FORCEON_YCLKA |
+                                             RADEON_FORCEON_YCLKB |
+                                             RADEON_FORCEON_MC |
+                                             RADEON_FORCEON_AIC ) );
 
        rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET );
 
@@ -566,23 +574,33 @@ static int radeon_do_engine_reset( drm_device_t *dev )
        return 0;
 }
 
-static void radeon_cp_init_ring_buffer( drm_device_t *dev )
+static void radeon_cp_init_ring_buffer( drm_device_t *dev,
+                                       drm_radeon_private_t *dev_priv )
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
        u32 ring_start, cur_read_ptr;
        u32 tmp;
 
        /* Initialize the memory controller */
        RADEON_WRITE( RADEON_MC_FB_LOCATION,
                      (dev_priv->agp_vm_start - 1) & 0xffff0000 );
-       RADEON_WRITE( RADEON_MC_AGP_LOCATION,
-                     (((dev_priv->agp_vm_start - 1 +
-                        dev_priv->agp_size) & 0xffff0000) |
-                      (dev_priv->agp_vm_start >> 16)) );
 
-       ring_start = (dev_priv->cp_ring->offset
-                     - dev->agp->base
-                     + dev_priv->agp_vm_start);
+       if ( !dev_priv->is_pci ) {
+               RADEON_WRITE( RADEON_MC_AGP_LOCATION,
+                             (((dev_priv->agp_vm_start - 1 +
+                                dev_priv->agp_size) & 0xffff0000) |
+                              (dev_priv->agp_vm_start >> 16)) );
+       }
+
+#if __REALLY_HAVE_AGP
+       if ( !dev_priv->is_pci )
+               ring_start = (dev_priv->cp_ring->offset
+                             - dev->agp->base
+                             + dev_priv->agp_vm_start);
+       else
+#endif
+               ring_start = (dev_priv->cp_ring->offset
+                             - dev->sg->handle
+                             + dev_priv->agp_vm_start);
 
        RADEON_WRITE( RADEON_CP_RB_BASE, ring_start );
 
@@ -595,17 +613,29 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
        *dev_priv->ring.head = cur_read_ptr;
        dev_priv->ring.tail = cur_read_ptr;
 
-       RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
+       if ( !dev_priv->is_pci ) {
+               RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+                             dev_priv->ring_rptr->offset );
+       } else {
+               drm_sg_mem_t *entry = dev->sg;
+               unsigned long tmp_ofs, page_ofs;
+
+               tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
+               page_ofs = tmp_ofs >> PAGE_SHIFT;
+
+               RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+                             virt_to_bus(entry->pagelist[page_ofs]->virtual));
+
+               DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
+                          virt_to_bus(entry->pagelist[page_ofs]->virtual),
+                          entry->handle + tmp_ofs );
+       }
 
        /* Set ring buffer size */
        RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
 
        radeon_do_wait_for_idle( dev_priv );
 
-       /* Turn off PCI GART */
-       tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN;
-       RADEON_WRITE( RADEON_AIC_CNTL, tmp );
-
        /* Turn on bus mastering */
        tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS;
        RADEON_WRITE( RADEON_BUS_CNTL, tmp );
@@ -621,32 +651,42 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
 static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 {
        drm_radeon_private_t *dev_priv;
-        int i;
+       struct list_head *list;
+       u32 tmp;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
+       dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
        if ( dev_priv == NULL )
                return -ENOMEM;
-       dev->dev_private = (void *)dev_priv;
 
        memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
 
        dev_priv->is_pci = init->is_pci;
 
-       /* We don't support PCI cards until PCI GART is implemented.
-        * Fail here so we can remove all checks for PCI cards around
-        * the CP ring code.
+#if !defined(PCIGART_ENABLED)
+       /* PCI support is not 100% working, so we disable it here.
         */
        if ( dev_priv->is_pci ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+               DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
+#endif
+
+       if ( dev_priv->is_pci && !dev->sg ) {
+               DRM_ERROR( "PCI GART memory not allocated!\n" );
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
                return -EINVAL;
        }
 
        dev_priv->usec_timeout = init->usec_timeout;
        if ( dev_priv->usec_timeout < 1 ||
             dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+               DRM_DEBUG( "TIMEOUT problem!\n" );
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
                return -EINVAL;
        }
 
@@ -662,8 +702,9 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
         */
        if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) &&
             ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
-               dev->dev_private = NULL;
+               DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
                return -EINVAL;
        }
 
@@ -722,55 +763,128 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
                                         RADEON_BFACE_SOLID |
                                         RADEON_FFACE_SOLID |
                                         RADEON_FLAT_SHADE_VTX_LAST |
-
                                         RADEON_DIFFUSE_SHADE_FLAT |
                                         RADEON_ALPHA_SHADE_FLAT |
                                         RADEON_SPECULAR_SHADE_FLAT |
                                         RADEON_FOG_SHADE_FLAT |
-
                                         RADEON_VTX_PIX_CENTER_OGL |
                                         RADEON_ROUND_MODE_TRUNC |
                                         RADEON_ROUND_PREC_8TH_PIX);
 
-       /* FIXME: We want multiple shared areas, including one shared
-        * only by the X Server and kernel module.
-        */
-       for ( i = 0 ; i < dev->map_count ; i++ ) {
-               if ( dev->maplist[i]->type == _DRM_SHM ) {
-                       dev_priv->sarea = dev->maplist[i];
-                       break;
-               }
+       list_for_each(list, &dev->maplist->head) {
+               drm_map_list_t *r_list = (drm_map_list_t *)list;
+               if( r_list->map &&
+                   r_list->map->type == _DRM_SHM &&
+                   r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+                       dev_priv->sarea = r_list->map;
+                       break;
+               }
+       }
+       if(!dev_priv->sarea) {
+               DRM_ERROR("could not find sarea!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
        }
 
-       DO_FIND_MAP( dev_priv->fb, init->fb_offset );
-       DO_FIND_MAP( dev_priv->mmio, init->mmio_offset );
-       DO_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
-       DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
-       DO_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+       DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
+       if(!dev_priv->fb) {
+               DRM_ERROR("could not find framebuffer!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+       if(!dev_priv->mmio) {
+               DRM_ERROR("could not find mmio region!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
+       if(!dev_priv->cp_ring) {
+               DRM_ERROR("could not find cp ring region!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
+       if(!dev_priv->ring_rptr) {
+               DRM_ERROR("could not find ring read pointer!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
+       DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+       if(!dev_priv->buffers) {
+               DRM_ERROR("could not find dma buffer region!\n");
+               dev->dev_private = (void *)dev_priv;
+               radeon_do_cleanup_cp(dev);
+               return -EINVAL;
+       }
 
        if ( !dev_priv->is_pci ) {
-               DO_FIND_MAP( dev_priv->agp_textures,
-                            init->agp_textures_offset );
+               DRM_FIND_MAP( dev_priv->agp_textures,
+                             init->agp_textures_offset );
+               if(!dev_priv->agp_textures) {
+                       DRM_ERROR("could not find agp texture region!\n");
+                       dev->dev_private = (void *)dev_priv;
+                       radeon_do_cleanup_cp(dev);
+                       return -EINVAL;
+               }
        }
 
        dev_priv->sarea_priv =
                (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
                                       init->sarea_priv_offset);
 
-       DO_IOREMAP( dev_priv->cp_ring );
-       DO_IOREMAP( dev_priv->ring_rptr );
-       DO_IOREMAP( dev_priv->buffers );
-#if 0
        if ( !dev_priv->is_pci ) {
-               DO_IOREMAP( dev_priv->agp_textures );
+               DRM_IOREMAP( dev_priv->cp_ring );
+               DRM_IOREMAP( dev_priv->ring_rptr );
+               DRM_IOREMAP( dev_priv->buffers );
+               if(!dev_priv->cp_ring->handle ||
+                  !dev_priv->ring_rptr->handle ||
+                  !dev_priv->buffers->handle) {
+                       DRM_ERROR("could not find ioremap agp regions!\n");
+                       dev->dev_private = (void *)dev_priv;
+                       radeon_do_cleanup_cp(dev);
+                       return -EINVAL;
+               }
+       } else {
+               dev_priv->cp_ring->handle =
+                       (void *)dev_priv->cp_ring->offset;
+               dev_priv->ring_rptr->handle =
+                       (void *)dev_priv->ring_rptr->offset;
+               dev_priv->buffers->handle = (void *)dev_priv->buffers->offset;
+
+               DRM_DEBUG( "dev_priv->cp_ring->handle %p\n",
+                          dev_priv->cp_ring->handle );
+               DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n",
+                          dev_priv->ring_rptr->handle );
+               DRM_DEBUG( "dev_priv->buffers->handle %p\n",
+                          dev_priv->buffers->handle );
        }
-#endif
+
 
        dev_priv->agp_size = init->agp_size;
        dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
-       dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
-                                       - dev->agp->base
-                                       + dev_priv->agp_vm_start);
+#if __REALLY_HAVE_AGP
+       if ( !dev_priv->is_pci )
+               dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+                                               - dev->agp->base
+                                               + dev_priv->agp_vm_start);
+       else
+#endif
+               dev_priv->agp_buffers_offset = (dev_priv->buffers->offset
+                                               - dev->sg->handle
+                                               + dev_priv->agp_vm_start);
+
+       DRM_DEBUG( "dev_priv->agp_size %d\n",
+                  dev_priv->agp_size );
+       DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n",
+                  dev_priv->agp_vm_start );
+       DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n",
+                  dev_priv->agp_buffers_offset );
 
        dev_priv->ring.head = ((__volatile__ u32 *)
                               dev_priv->ring_rptr->handle);
@@ -779,11 +893,13 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
        dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle
                              + init->ring_size / sizeof(u32));
        dev_priv->ring.size = init->ring_size;
-       dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 );
+       dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 );
 
        dev_priv->ring.tail_mask =
                (dev_priv->ring.size / sizeof(u32)) - 1;
 
+       dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
 #if 0
        /* Initialize the scratch register pointer.  This will cause
         * the scratch register values to be written out to memory
@@ -812,33 +928,72 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
        RADEON_WRITE( RADEON_LAST_CLEAR_REG,
                      dev_priv->sarea_priv->last_clear );
 
+       if ( dev_priv->is_pci ) {
+               dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
+               if ( !dev_priv->phys_pci_gart ) {
+                       DRM_ERROR( "failed to init PCI GART!\n" );
+                       dev->dev_private = (void *)dev_priv;
+                       radeon_do_cleanup_cp(dev);
+                       return -ENOMEM;
+               }
+               /* Turn on PCI GART
+                */
+               tmp = RADEON_READ( RADEON_AIC_CNTL )
+                     | RADEON_PCIGART_TRANSLATE_EN;
+               RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+
+               /* set PCI GART page-table base address
+                */
+               RADEON_WRITE( RADEON_AIC_PT_BASE,
+                             virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+
+               /* set address range for PCI address translate
+                */
+               RADEON_WRITE( RADEON_AIC_LO_ADDR, dev_priv->agp_vm_start );
+               RADEON_WRITE( RADEON_AIC_HI_ADDR, dev_priv->agp_vm_start
+                                                 + dev_priv->agp_size - 1);
+
+               /* Turn off AGP aperture -- is this required for PCIGART?
+                */
+               RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
+               RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
+       } else {
+               /* Turn off PCI GART
+                */
+               tmp = RADEON_READ( RADEON_AIC_CNTL )
+                     & ~RADEON_PCIGART_TRANSLATE_EN;
+               RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+       }
+
        radeon_cp_load_microcode( dev_priv );
-       radeon_cp_init_ring_buffer( dev );
-       radeon_do_engine_reset( dev );
+       radeon_cp_init_ring_buffer( dev, dev_priv );
 
 #if ROTATE_BUFS
        dev_priv->last_buf = 0;
 #endif
 
+       dev->dev_private = (void *)dev_priv;
+
+       radeon_do_engine_reset( dev );
+
        return 0;
 }
 
-static int radeon_do_cleanup_cp( drm_device_t *dev )
+int radeon_do_cleanup_cp( drm_device_t *dev )
 {
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
        if ( dev->dev_private ) {
                drm_radeon_private_t *dev_priv = dev->dev_private;
 
-               DO_IOREMAPFREE( dev_priv->cp_ring );
-               DO_IOREMAPFREE( dev_priv->ring_rptr );
-               DO_IOREMAPFREE( dev_priv->buffers );
-#if 0
                if ( !dev_priv->is_pci ) {
-                       DO_IOREMAPFREE( dev_priv->agp_textures );
+                       DRM_IOREMAPFREE( dev_priv->cp_ring );
+                       DRM_IOREMAPFREE( dev_priv->ring_rptr );
+                       DRM_IOREMAPFREE( dev_priv->buffers );
                }
-#endif
 
-               drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
-                         DRM_MEM_DRIVER );
+               DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
+                          DRM_MEM_DRIVER );
                dev->dev_private = NULL;
        }
 
@@ -873,11 +1028,8 @@ int radeon_cp_start( struct inode *inode, struct file *filp,
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
        if ( dev_priv->cp_running ) {
                DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
                return 0;
@@ -906,11 +1058,7 @@ int radeon_cp_stop( struct inode *inode, struct file *filp,
        int ret;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
                return -EFAULT;
@@ -952,11 +1100,8 @@ int radeon_cp_reset( struct inode *inode, struct file *filp,
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
        if ( !dev_priv ) {
                DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
                return -EINVAL;
@@ -978,11 +1123,7 @@ int radeon_cp_idle( struct inode *inode, struct file *filp,
        drm_radeon_private_t *dev_priv = dev->dev_private;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        return radeon_do_cp_idle( dev_priv );
 }
@@ -994,11 +1135,7 @@ int radeon_engine_reset( struct inode *inode, struct file *filp,
         drm_device_t *dev = priv->dev;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        return radeon_do_engine_reset( dev );
 }
@@ -1048,11 +1185,7 @@ int radeon_fullscreen( struct inode *inode, struct file *filp,
         drm_device_t *dev = priv->dev;
        drm_radeon_fullscreen_t fs;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
                             sizeof(fs) ) )
@@ -1085,8 +1218,8 @@ static int radeon_freelist_init( drm_device_t *dev )
        drm_radeon_freelist_t *entry;
        int i;
 
-       dev_priv->head = drm_alloc( sizeof(drm_radeon_freelist_t),
-                                   DRM_MEM_DRIVER );
+       dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t),
+                                    DRM_MEM_DRIVER );
        if ( dev_priv->head == NULL )
                return -ENOMEM;
 
@@ -1097,8 +1230,8 @@ static int radeon_freelist_init( drm_device_t *dev )
                buf = dma->buflist[i];
                buf_priv = buf->dev_private;
 
-               entry = drm_alloc( sizeof(drm_radeon_freelist_t),
-                                  DRM_MEM_DRIVER );
+               entry = DRM(alloc)( sizeof(drm_radeon_freelist_t),
+                                   DRM_MEM_DRIVER );
                if ( !entry ) return -ENOMEM;
 
                entry->age = RADEON_BUFFER_FREE;
@@ -1218,32 +1351,20 @@ int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n )
        int i;
 
        for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-               ring->space = *ring->head - ring->tail;
-               if ( ring->space <= 0 )
-                       ring->space += ring->size;
-
-               if ( ring->space >= n )
+               radeon_update_ring_snapshot( ring );
+               if ( ring->space > n )
                        return 0;
-
                udelay( 1 );
        }
 
        /* FIXME: This return value is ignored in the BEGIN_RING macro! */
+#if RADEON_FIFO_DEBUG
+       radeon_status( dev_priv );
        DRM_ERROR( "failed!\n" );
+#endif
        return -EBUSY;
 }
 
-void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv )
-{
-       drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
-
-       ring->space = *ring->head - ring->tail;
-       if ( ring->space == 0 )
-               atomic_inc( &dev_priv->idle_count );
-       if ( ring->space <= 0 )
-               ring->space += ring->size;
-}
-
 static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
 {
        int i;
@@ -1276,14 +1397,10 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
        int ret = 0;
        drm_dma_t d;
 
-       if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
-               return -EFAULT;
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
+               return -EFAULT;
 
        /* Please don't send us buffers.
         */
@@ -1307,7 +1424,7 @@ int radeon_cp_buffers( struct inode *inode, struct file *filp,
                ret = radeon_cp_get_buffers( dev, &d );
        }
 
-       if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
+       if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
                return -EFAULT;
 
        return ret;
index c5f9f66d17856db1e3ef09f8058fe789959ef46c..4ae387ff01495b0b67997138631383bcf3c1db09 100644 (file)
@@ -26,7 +26,6 @@
  * Authors:
  *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
  */
 
 #ifndef __RADEON_DRM_H__
@@ -74,7 +73,7 @@
 
 /* Vertex/indirect buffer size
  */
-#define RADEON_BUFFER_SIZE             16384
+#define RADEON_BUFFER_SIZE             65536
 
 /* Byte offsets for indirect buffer data
  */
@@ -237,7 +236,7 @@ typedef struct drm_radeon_init {
                RADEON_INIT_CP    = 0x01,
                RADEON_CLEANUP_CP = 0x02
        } func;
-       int sarea_priv_offset;
+       unsigned long sarea_priv_offset;
        int is_pci;
        int cp_mode;
        int agp_size;
@@ -250,12 +249,12 @@ typedef struct drm_radeon_init {
        unsigned int depth_bpp;
        unsigned int depth_offset, depth_pitch;
 
-       unsigned int fb_offset;
-       unsigned int mmio_offset;
-       unsigned int ring_offset;
-       unsigned int ring_rptr_offset;
-       unsigned int buffers_offset;
-       unsigned int agp_textures_offset;
+       unsigned long fb_offset;
+       unsigned long mmio_offset;
+       unsigned long ring_offset;
+       unsigned long ring_rptr_offset;
+       unsigned long buffers_offset;
+       unsigned long agp_textures_offset;
 } drm_radeon_init_t;
 
 typedef struct drm_radeon_cp_stop {
@@ -276,15 +275,18 @@ typedef struct drm_radeon_fullscreen {
 #define CLEAR_Y2       3
 #define CLEAR_DEPTH    4
 
+typedef union drm_radeon_clear_rect {
+       float f[5];
+       unsigned int ui[5];
+} drm_radeon_clear_rect_t;
+
 typedef struct drm_radeon_clear {
        unsigned int flags;
-       int x, y, w, h;
        unsigned int clear_color;
        unsigned int clear_depth;
-       union {
-               float f[5];
-               unsigned int ui[5];
-       } rect;
+       unsigned int color_mask;
+       unsigned int depth_mask;
+       drm_radeon_clear_rect_t *depth_boxes;
 } drm_radeon_clear_t;
 
 typedef struct drm_radeon_vertex {
@@ -302,14 +304,20 @@ typedef struct drm_radeon_indices {
        int discard;                    /* Client finished with buffer? */
 } drm_radeon_indices_t;
 
-typedef struct drm_radeon_blit {
-       int idx;
-       int pitch;
+typedef struct drm_radeon_tex_image {
+       unsigned int x, y;              /* Blit coordinates */
+       unsigned int width, height;
+       const void *data;
+} drm_radeon_tex_image_t;
+
+typedef struct drm_radeon_texture {
        int offset;
+       int pitch;
        int format;
-       unsigned short x, y;
-       unsigned short width, height;
-} drm_radeon_blit_t;
+       int width;                      /* Texture image coordinates */
+       int height;
+       drm_radeon_tex_image_t *image;
+} drm_radeon_texture_t;
 
 typedef struct drm_radeon_stipple {
        unsigned int *mask;
index 0113ed97c2a78164099634bcc56cf0292eaa48a2..49599bc82587423d3ccc84a80e349c3cd2e12701 100644 (file)
@@ -1,7 +1,7 @@
 /* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
+ * Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
  *
- * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * 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
+ * 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: Kevin E. Martin <martin@valinux.com>
- *          Rickard E. (Rik) Faith <faith@valinux.com>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #include <linux/config.h>
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
+#include "ati_pcigart.h"
+
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "radeon"
+#define DRIVER_DESC            "ATI Radeon"
+#define DRIVER_DATE            "20010405"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      1
+
+#define DRIVER_IOCTLS                                                       \
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]    = { radeon_cp_init,     1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)]   = { radeon_cp_start,    1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]    = { radeon_cp_stop,     1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]   = { radeon_cp_reset,    1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]    = { radeon_cp_idle,     1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)]    = { radeon_engine_reset,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]       = { radeon_cp_swap,     1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]      = { radeon_cp_clear,    1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]     = { radeon_cp_vertex,   1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)]    = { radeon_cp_indices,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)]    = { radeon_cp_texture,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)]    = { radeon_cp_stipple,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]   = { radeon_cp_indirect, 1, 1 },
 
-#define RADEON_NAME            "radeon"
-#define RADEON_DESC            "ATI Radeon"
-#define RADEON_DATE            "20010105"
-#define RADEON_MAJOR           1
-#define RADEON_MINOR           0
-#define RADEON_PATCHLEVEL      0
-
-static drm_device_t          radeon_device;
-drm_ctx_t                    radeon_res_ctx;
-
-static struct file_operations radeon_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#endif
-       open:    radeon_open,
-       flush:   drm_flush,
-       release: radeon_release,
-       ioctl:   radeon_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
-
-static struct miscdevice      radeon_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  RADEON_NAME,
-       fops:  &radeon_fops,
-};
 
-static drm_ioctl_desc_t              radeon_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { radeon_version,     0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { drm_getunique,      0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { drm_getmagic,       0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { drm_irq_busid,      0, 1 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { drm_setunique,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]         = { drm_block,          1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { drm_unblock,        1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { drm_authmagic,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { drm_addmap,         1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { radeon_addbufs,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { drm_markbufs,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { drm_infobufs,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { radeon_mapbufs,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { drm_freebufs,       1, 0 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { radeon_addctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { radeon_rmctx,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { radeon_modctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { radeon_getctx,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { radeon_switchctx,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { radeon_newctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { radeon_resctx,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { drm_adddraw,        1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { drm_rmdraw,         1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]           = { radeon_cp_buffers,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]          = { radeon_lock,        1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { radeon_unlock,      1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { drm_finish,         1, 0 },
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { drm_agp_acquire,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release,    1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,     1, 1 },
+#if 0
+/* GH: Count data sent to card via ring or vertex/indirect buffers.
+ */
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
 #endif
 
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]  = { radeon_cp_init,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]  = { radeon_cp_stop,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]  = { radeon_cp_idle,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]    = { radeon_cp_swap,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]   = { radeon_cp_clear,   1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]  = { radeon_cp_vertex,  1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)]    = { radeon_cp_blit,    1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
-};
-#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
-
-#ifdef MODULE
-static char                  *radeon = NULL;
-#endif
 
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("radeon");
-MODULE_PARM(radeon, "s");
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
 #ifndef MODULE
-/* radeon_options is called by the kernel to parse command-line options
+/* DRM(options) is called by the kernel to parse command-line options
  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
  * routine, drm_parse_drm.
  */
 
-static int __init radeon_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init radeon_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("radeon=", radeon_options);
-#endif
-
-static int radeon_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       drm_dma_setup(dev);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp         = dev->buf;
-       dev->buf_wp         = dev->buf;
-       dev->buf_end        = dev->buf + DRM_BSZ;
-       dev->buf_async      = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       radeon_res_ctx.handle = -1;
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int radeon_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-                               /* Clear AGP information */
-       if (dev->agp) {
-               drm_agp_mem_t *entry;
-               drm_agp_mem_t *nexte;
-
-                               /* Remove AGP resources, but leave dev->agp
-                                   intact until radeon_cleanup is called. */
-               for (entry = dev->agp->memory; entry; entry = nexte) {
-                       nexte = entry->next;
-                       if (entry->bound) drm_unbind_agp(entry->memory);
-                       drm_free_agp(entry->memory, entry->pages);
-                       drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
-               }
-               dev->agp->memory = NULL;
-
-               if (dev->agp->acquired) _drm_agp_release();
-
-               dev->agp->acquired = 0;
-               dev->agp->enabled  = 0;
-       }
-#endif
-
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
-#endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                   handled in the AGP/GART driver. */
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       drm_dma_takedown(dev);
-
-       dev->queue_count     = 0;
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-/* radeon_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init radeon_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &radeon_device;
-
-       DRM_DEBUG("\n");
-
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
-
-#ifdef MODULE
-       drm_parse_options(radeon);
-#endif
-
-       if ((retcode = misc_register(&radeon_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", RADEON_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, radeon_misc.minor);
-       dev->name   = RADEON_NAME;
-
-       drm_mem_init();
-       drm_proc_init(dev);
-
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       dev->agp    = drm_agp_init();
-       if (dev->agp == NULL) {
-               DRM_ERROR("Cannot initialize agpgart module.\n");
-               drm_proc_cleanup();
-               misc_deregister(&radeon_misc);
-               radeon_takedown(dev);
-               return -ENOMEM;
-       }
-
-#ifdef CONFIG_MTRR
-       dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
-                                     dev->agp->agp_info.aper_size*1024*1024,
-                                     MTRR_TYPE_WRCOMB,
-                                     1);
+__setup( DRIVER_NAME "=", radeon_options );
 #endif
-#endif
-
-       if((retcode = drm_ctxbitmap_init(dev))) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               drm_proc_cleanup();
-               misc_deregister(&radeon_misc);
-               radeon_takedown(dev);
-               return retcode;
-       }
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-                RADEON_NAME,
-                RADEON_MAJOR,
-                RADEON_MINOR,
-                RADEON_PATCHLEVEL,
-                RADEON_DATE,
-                radeon_misc.minor);
-
-       return 0;
-}
-
-/* radeon_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit radeon_cleanup(void)
-{
-       drm_device_t          *dev = &radeon_device;
 
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&radeon_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       drm_ctxbitmap_cleanup(dev);
-       radeon_takedown(dev);
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       if (dev->agp) {
-               drm_agp_uninit();
-               drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-               dev->agp = NULL;
-       }
-#endif
-}
-
-module_init(radeon_init);
-module_exit(radeon_cleanup);
-
-
-int radeon_version(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                \
-       len = strlen(value);                                 \
-       if (len > name##_len) len = name##_len;              \
-       name##_len = strlen(value);                          \
-       if (len && name) {                                   \
-               if (copy_to_user(name, value, len))          \
-                       return -EFAULT;                      \
-       }
-
-       version.version_major      = RADEON_MAJOR;
-       version.version_minor      = RADEON_MINOR;
-       version.version_patchlevel = RADEON_PATCHLEVEL;
-
-       DRM_COPY(version.name, RADEON_NAME);
-       DRM_COPY(version.date, RADEON_DATE);
-       DRM_COPY(version.desc, RADEON_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int radeon_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &radeon_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return radeon_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       return retcode;
-}
-
-int radeon_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev = priv->dev;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-
-       /* Force the cleanup of page flipping when required */
-       if ( dev->dev_private ) {
-               drm_radeon_private_t *dev_priv = dev->dev_private;
-               if ( dev_priv->page_flipping ) {
-                       radeon_do_cleanup_pageflip( dev );
-               }
-       }
-
-       if (!(retcode = drm_release(inode, filp))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_close);
-               spin_lock(&dev->count_lock);
-               if (!--dev->open_count) {
-                       if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                               DRM_ERROR("Device busy: %d %d\n",
-                                         atomic_read(&dev->ioctl_count),
-                                         dev->blocked);
-                               spin_unlock(&dev->count_lock);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return radeon_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return retcode;
-}
-
-/* radeon_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-
-int radeon_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= RADEON_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &radeon_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-        drm_file_t        *priv   = filp->private_data;
-        drm_device_t      *dev    = priv->dev;
-        DECLARE_WAITQUEUE(entry, current);
-        int               ret   = 0;
-        drm_lock_t        lock;
-#if DRM_DMA_HISTOGRAM
-        cycles_t          start;
-
-        dev->lck_start = start = get_cycles();
-#endif
-
-        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-        if (lock.context == DRM_KERNEL_CONTEXT) {
-                DRM_ERROR("Process %d using kernel context %d\n",
-                          current->pid, lock.context);
-                return -EINVAL;
-        }
-
-        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                  lock.context, current->pid, dev->lock.hw_lock->lock,
-                  lock.flags);
-
-        if (lock.context < 0 /* || lock.context >= dev->queue_count */)
-                return -EINVAL;
-
-        if (!ret) {
-                add_wait_queue(&dev->lock.lock_queue, &entry);
-                for (;;) {
-                        current->state = TASK_INTERRUPTIBLE;
-                        if (!dev->lock.hw_lock) {
-                                /* Device has been unregistered */
-                                ret = -EINTR;
-                                break;
-                        }
-                        if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                          lock.context)) {
-                                dev->lock.pid       = current->pid;
-                                dev->lock.lock_time = jiffies;
-                                atomic_inc(&dev->total_locks);
-                                break;  /* Got lock */
-                        }
-
-                                /* Contention */
-                        atomic_inc(&dev->total_sleeps);
-                        schedule();
-                        if (signal_pending(current)) {
-                                ret = -ERESTARTSYS;
-                                break;
-                        }
-                }
-                current->state = TASK_RUNNING;
-                remove_wait_queue(&dev->lock.lock_queue, &entry);
-        }
-
-        if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-                if (lock.flags & _DRM_LOCK_READY) {
-                               /* Wait for space in DMA/FIFO */
-               }
-                if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                               /* Make hardware quiescent */
-                       DRM_DEBUG("not quiescent!\n");
-#if 0
-                        radeon_quiescent(dev);
-#endif
-               }
-        }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != radeon_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY/4;
-       }
-#endif
-        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
-#endif
-
-        return ret;
-}
-
-
-int radeon_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-                               /* FIXME: Try to send data to card here */
-       if (!dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != radeon_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY;
-       }
-#endif
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
+#include "drm_scatter.h"
index 06b541991e528e7dbb5a9b41ef87457eb9546152..4217beee92ab33ea796965654e7ee6d429f2966f 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Rickard E. (Rik) Faith <faith@valinux.com>
- *   Kevin E. Martin <martin@valinux.com>
- *   Gareth Hughes <gareth@valinux.com>
- *
+ *    Kevin E. Martin <martin@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #ifndef __RADEON_DRV_H__
@@ -50,6 +48,8 @@ typedef struct drm_radeon_ring_buffer {
        u32 tail;
        u32 tail_mask;
        int space;
+
+       int high_mark;
 } drm_radeon_ring_buffer_t;
 
 typedef struct drm_radeon_depth_clear_t {
@@ -64,7 +64,7 @@ typedef struct drm_radeon_private {
 
        int agp_size;
        u32 agp_vm_start;
-       u32 agp_buffers_offset;
+       unsigned long agp_buffers_offset;
 
        int cp_mode;
        int cp_running;
@@ -83,6 +83,7 @@ typedef struct drm_radeon_private {
 
        int usec_timeout;
        int is_pci;
+       unsigned long phys_pci_gart;
 
        atomic_t idle_count;
 
@@ -91,13 +92,13 @@ typedef struct drm_radeon_private {
        u32 crtc_offset;
        u32 crtc_offset_cntl;
 
-       unsigned int color_fmt;
+       u32 color_fmt;
        unsigned int front_offset;
        unsigned int front_pitch;
        unsigned int back_offset;
        unsigned int back_pitch;
 
-       unsigned int depth_fmt;
+       u32 depth_fmt;
        unsigned int depth_offset;
        unsigned int depth_pitch;
 
@@ -124,18 +125,6 @@ typedef struct drm_radeon_buf_priv {
        drm_radeon_freelist_t *list_entry;
 } drm_radeon_buf_priv_t;
 
-                               /* radeon_drv.c */
-extern int  radeon_version( struct inode *inode, struct file *filp,
-                           unsigned int cmd, unsigned long arg );
-extern int  radeon_open( struct inode *inode, struct file *filp );
-extern int  radeon_release( struct inode *inode, struct file *filp );
-extern int  radeon_ioctl( struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg );
-extern int  radeon_lock( struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg );
-extern int  radeon_unlock( struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg );
-
                                /* radeon_cp.c */
 extern int radeon_cp_init( struct inode *inode, struct file *filp,
                           unsigned int cmd, unsigned long arg );
@@ -158,9 +147,17 @@ extern void radeon_freelist_reset( drm_device_t *dev );
 extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
 
 extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
-extern void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv );
+
+static inline void
+radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
+{
+       ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32);
+       if ( ring->space <= 0 )
+               ring->space += ring->size;
+}
 
 extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
+extern int radeon_do_cleanup_cp( drm_device_t *dev );
 extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
 
                                /* radeon_state.c */
@@ -172,43 +169,19 @@ extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
                             unsigned int cmd, unsigned long arg );
 extern int radeon_cp_indices( struct inode *inode, struct file *filp,
                              unsigned int cmd, unsigned long arg );
-extern int radeon_cp_blit( struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg );
+extern int radeon_cp_texture( struct inode *inode, struct file *filp,
+                             unsigned int cmd, unsigned long arg );
 extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
                              unsigned int cmd, unsigned long arg );
 extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
                               unsigned int cmd, unsigned long arg );
 
-                               /* radeon_bufs.c */
-extern int radeon_addbufs(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int radeon_mapbufs(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-
-                               /* radeon_context.c */
-extern int  radeon_resctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  radeon_addctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  radeon_modctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  radeon_getctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  radeon_switchctx(struct inode *inode, struct file *filp,
-                            unsigned int cmd, unsigned long arg);
-extern int  radeon_newctx(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  radeon_rmctx(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-
-extern int  radeon_context_switch(drm_device_t *dev, int old, int new);
-extern int  radeon_context_switch_complete(drm_device_t *dev, int new);
-
 
 /* Register definitions, register access macros and drmAddMap constants
  * for Radeon kernel driver.
  */
 
+#define RADEON_AGP_COMMAND             0x0f60
 #define RADEON_AUX_SCISSOR_CNTL                0x26f0
 #      define RADEON_EXCLUSIVE_SCISSOR_0       (1 << 24)
 #      define RADEON_EXCLUSIVE_SCISSOR_1       (1 << 25)
@@ -282,6 +255,12 @@ extern int  radeon_context_switch_complete(drm_device_t *dev, int new);
 #define RADEON_MC_AGP_LOCATION         0x014c
 #define RADEON_MC_FB_LOCATION          0x0148
 #define RADEON_MCLK_CNTL               0x0012
+#      define RADEON_FORCEON_MCLKA             (1 << 16)
+#      define RADEON_FORCEON_MCLKB             (1 << 17)
+#      define RADEON_FORCEON_YCLKA             (1 << 18)
+#      define RADEON_FORCEON_YCLKB             (1 << 19)
+#      define RADEON_FORCEON_MC                (1 << 20)
+#      define RADEON_FORCEON_AIC               (1 << 21)
 
 #define RADEON_PP_BORDER_COLOR_0       0x1d40
 #define RADEON_PP_BORDER_COLOR_1       0x1d44
@@ -462,6 +441,12 @@ extern int  radeon_context_switch_complete(drm_device_t *dev, int new);
 
 #define RADEON_AIC_CNTL                        0x01d0
 #      define RADEON_PCIGART_TRANSLATE_EN      (1 << 0)
+#define RADEON_AIC_STAT                        0x01d4
+#define RADEON_AIC_PT_BASE             0x01d8
+#define RADEON_AIC_LO_ADDR             0x01dc
+#define RADEON_AIC_HI_ADDR             0x01e0
+#define RADEON_AIC_TLB_ADDR            0x01e4
+#define RADEON_AIC_TLB_DATA            0x01e8
 
 /* CP command packets */
 #define RADEON_CP_PACKET0              0x00000000
@@ -514,14 +499,14 @@ extern int  radeon_context_switch_complete(drm_device_t *dev, int new);
 #define RADEON_COLOR_FORMAT_RGB8       9
 #define RADEON_COLOR_FORMAT_ARGB4444   15
 
-#define RADEON_TXF_8BPP_I              0
-#define RADEON_TXF_16BPP_AI88          1
-#define RADEON_TXF_8BPP_RGB332         2
-#define RADEON_TXF_16BPP_ARGB1555      3
-#define RADEON_TXF_16BPP_RGB565                4
-#define RADEON_TXF_16BPP_ARGB4444      5
-#define RADEON_TXF_32BPP_ARGB8888      6
-#define RADEON_TXF_32BPP_RGBA8888      7
+#define RADEON_TXFORMAT_I8             0
+#define RADEON_TXFORMAT_AI88           1
+#define RADEON_TXFORMAT_RGB332         2
+#define RADEON_TXFORMAT_ARGB1555       3
+#define RADEON_TXFORMAT_RGB565         4
+#define RADEON_TXFORMAT_ARGB4444       5
+#define RADEON_TXFORMAT_ARGB8888       6
+#define RADEON_TXFORMAT_RGBA8888       7
 
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT                100000  /* 100 ms */
@@ -534,27 +519,56 @@ extern int  radeon_context_switch_complete(drm_device_t *dev, int new);
 #define RADEON_MAX_VB_AGE              0x7fffffff
 #define RADEON_MAX_VB_VERTS            (0xffff)
 
+#define RADEON_RING_HIGH_MARK          128
 
-#define RADEON_BASE(reg)       ((u32)(dev_priv->mmio->handle))
-#define RADEON_ADDR(reg)       (RADEON_BASE(reg) + reg)
 
-#define RADEON_DEREF(reg)      *(__volatile__ u32 *)RADEON_ADDR(reg)
-#define RADEON_READ(reg)       RADEON_DEREF(reg)
-#define RADEON_WRITE(reg,val)  do { RADEON_DEREF(reg) = val; } while (0)
+#define RADEON_BASE(reg)       ((unsigned long)(dev_priv->mmio->handle))
+#define RADEON_ADDR(reg)       (RADEON_BASE( reg ) + reg)
 
-#define RADEON_DEREF8(reg)     *(__volatile__ u8 *)RADEON_ADDR(reg)
-#define RADEON_READ8(reg)      RADEON_DEREF8(reg)
-#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0)
+#define RADEON_DEREF(reg)      *(volatile u32 *)RADEON_ADDR( reg )
+#ifdef __alpha__
+#define RADEON_READ(reg)       (_RADEON_READ((u32 *)RADEON_ADDR( reg )))
+static inline u32 _RADEON_READ(u32 *addr)
+{
+       mb();
+       return *(volatile u32 *)addr;
+}
+#define RADEON_WRITE(reg,val)                                          \
+do {                                                                   \
+       wmb();                                                          \
+       RADEON_DEREF(reg) = val;                                        \
+} while (0)
+#else
+#define RADEON_READ(reg)       RADEON_DEREF( reg )
+#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
+#endif
 
-#define RADEON_WRITE_PLL(addr,val)                                            \
-do {                                                                          \
-       RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX,                                \
-                     ((addr) & 0x1f) | RADEON_PLL_WR_EN);                    \
-       RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val));                          \
+#define RADEON_DEREF8(reg)     *(volatile u8 *)RADEON_ADDR( reg )
+#ifdef __alpha__
+#define RADEON_READ8(reg)      _RADEON_READ8((u8 *)RADEON_ADDR( reg ))
+static inline u8 _RADEON_READ8(u8 *addr)
+{
+       mb();
+       return *(volatile u8 *)addr;
+}
+#define RADEON_WRITE8(reg,val)                                         \
+do {                                                                   \
+       wmb();                                                          \
+       RADEON_DEREF8( reg ) = val;                                     \
 } while (0)
+#else
+#define RADEON_READ8(reg)      RADEON_DEREF8( reg )
+#define RADEON_WRITE8(reg, val)        do { RADEON_DEREF8( reg ) = val; } while (0)
+#endif
 
-extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
+#define RADEON_WRITE_PLL( addr, val )                                  \
+do {                                                                   \
+       RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX,                         \
+                      ((addr) & 0x1f) | RADEON_PLL_WR_EN );            \
+       RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) );                  \
+} while (0)
 
+extern int RADEON_READ_PLL( drm_device_t *dev, int addr );
 
 
 #define CP_PACKET0( reg, n )                                           \
@@ -573,54 +587,46 @@ extern int RADEON_READ_PLL(drm_device_t *dev, int addr);
  * Engine control helper macros
  */
 
-#define RADEON_WAIT_UNTIL_2D_IDLE()                                    \
-do {                                                                   \
+#define RADEON_WAIT_UNTIL_2D_IDLE() do {                               \
        OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );                 \
        OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |                           \
                   RADEON_WAIT_HOST_IDLECLEAN) );                       \
 } while (0)
 
-#define RADEON_WAIT_UNTIL_3D_IDLE()                                    \
-do {                                                                   \
+#define RADEON_WAIT_UNTIL_3D_IDLE() do {                               \
        OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );                 \
        OUT_RING( (RADEON_WAIT_3D_IDLECLEAN |                           \
                   RADEON_WAIT_HOST_IDLECLEAN) );                       \
 } while (0)
 
-#define RADEON_WAIT_UNTIL_IDLE()                                       \
-do {                                                                   \
+#define RADEON_WAIT_UNTIL_IDLE() do {                                  \
        OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );                 \
        OUT_RING( (RADEON_WAIT_2D_IDLECLEAN |                           \
                   RADEON_WAIT_3D_IDLECLEAN |                           \
                   RADEON_WAIT_HOST_IDLECLEAN) );                       \
 } while (0)
 
-#define RADEON_WAIT_UNTIL_PAGE_FLIPPED()                               \
-do {                                                                   \
+#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do {                          \
        OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) );                 \
        OUT_RING( RADEON_WAIT_CRTC_PFLIP );                             \
 } while (0)
 
-#define RADEON_FLUSH_CACHE()                                           \
-do {                                                                   \
+#define RADEON_FLUSH_CACHE() do {                                      \
        OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) );      \
        OUT_RING( RADEON_RB2D_DC_FLUSH );                               \
 } while (0)
 
-#define RADEON_PURGE_CACHE()                                           \
-do {                                                                   \
+#define RADEON_PURGE_CACHE() do {                                      \
        OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) );      \
        OUT_RING( RADEON_RB2D_DC_FLUSH_ALL );                           \
 } while (0)
 
-#define RADEON_FLUSH_ZCACHE()                                          \
-do {                                                                   \
+#define RADEON_FLUSH_ZCACHE() do {                                     \
        OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) );        \
        OUT_RING( RADEON_RB3D_ZC_FLUSH );                               \
 } while (0)
 
-#define RADEON_PURGE_ZCACHE()                                          \
-do {                                                                   \
+#define RADEON_PURGE_ZCACHE() do {                                     \
        OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) );        \
        OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL );                           \
 } while (0)
@@ -630,7 +636,33 @@ do {                                                                       \
  * Misc helper macros
  */
 
-#define VB_AGE_CHECK_WITH_RET( dev_priv )                              \
+#define LOCK_TEST_WITH_RETURN( dev )                                   \
+do {                                                                   \
+       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||           \
+            dev->lock.pid != current->pid ) {                          \
+               DRM_ERROR( "%s called without lock held\n",             \
+                          __FUNCTION__ );                              \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+#define RING_SPACE_TEST_WITH_RETURN( dev_priv )                                \
+do {                                                                   \
+       drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i;        \
+       if ( ring->space < ring->high_mark ) {                          \
+               for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {      \
+                       radeon_update_ring_snapshot( ring );            \
+                       if ( ring->space >= ring->high_mark )           \
+                               goto __ring_space_done;                 \
+                       udelay( 1 );                                    \
+               }                                                       \
+               DRM_ERROR( "ring space check failed!\n" );              \
+               return -EBUSY;                                          \
+       }                                                               \
+ __ring_space_done:                                                    \
+} while (0)
+
+#define VB_AGE_TEST_WITH_RETURN( dev_priv )                            \
 do {                                                                   \
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;          \
        if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) {         \
@@ -641,20 +673,17 @@ do {                                                                      \
        }                                                               \
 } while (0)
 
-#define RADEON_DISPATCH_AGE( age )                                     \
-do {                                                                   \
+#define RADEON_DISPATCH_AGE( age ) do {                                        \
        OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) );          \
        OUT_RING( age );                                                \
 } while (0)
 
-#define RADEON_FRAME_AGE( age )                                                \
-do {                                                                   \
+#define RADEON_FRAME_AGE( age ) do {                                   \
        OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) );             \
        OUT_RING( age );                                                \
 } while (0)
 
-#define RADEON_CLEAR_AGE( age )                                                \
-do {                                                                   \
+#define RADEON_CLEAR_AGE( age ) do {                                   \
        OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) );             \
        OUT_RING( age );                                                \
 } while (0)
@@ -676,7 +705,7 @@ do {                                                                        \
                DRM_INFO( "BEGIN_RING( %d ) in %s\n",                   \
                           n, __FUNCTION__ );                           \
        }                                                               \
-       if ( dev_priv->ring.space < (n) * sizeof(u32) ) {               \
+       if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {              \
                radeon_wait_ring( dev_priv, (n) * sizeof(u32) );        \
        }                                                               \
        dev_priv->ring.space -= (n) * sizeof(u32);                      \
@@ -687,7 +716,7 @@ do {                                                                        \
 
 #define ADVANCE_RING() do {                                            \
        if ( RADEON_VERBOSE ) {                                         \
-               DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n",     \
+               DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
                          write, dev_priv->ring.tail );                 \
        }                                                               \
        radeon_flush_write_combine();                                   \
index 1a4da800574e46fca291a52f8b4ead865e3b3c81..0a209245bef05d6141f3520866544f50e81b9caa 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *    Kevin E. Martin <martin@valinux.com>
  *    Gareth Hughes <gareth@valinux.com>
- *
+ *    Kevin E. Martin <martin@valinux.com>
  */
 
 #define __NO_VERSION__
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
 #include "drm.h"
@@ -486,7 +486,8 @@ static void radeon_print_dirty( const char *msg, unsigned int flags )
 }
 
 static void radeon_cp_dispatch_clear( drm_device_t *dev,
-                                     drm_radeon_clear_t *clear )
+                                     drm_radeon_clear_t *clear,
+                                     drm_radeon_clear_rect_t *depth_boxes )
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -497,8 +498,6 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       radeon_update_ring_snapshot( dev_priv );
-
        if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
                unsigned int tmp = flags;
 
@@ -525,7 +524,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
                        RADEON_WAIT_UNTIL_3D_IDLE();
 
                        OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
-                       OUT_RING( sarea_priv->context_state.rb3d_planemask );
+                       OUT_RING( clear->color_mask );
 
                        ADVANCE_RING();
 
@@ -609,17 +608,17 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
                                   RADEON_VTX_FMT_RADEON_MODE |
                                   (3 << RADEON_NUM_VERTICES_SHIFT)) );
 
-                       OUT_RING( clear->rect.ui[CLEAR_X1] );
-                       OUT_RING( clear->rect.ui[CLEAR_Y1] );
-                       OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
 
-                       OUT_RING( clear->rect.ui[CLEAR_X1] );
-                       OUT_RING( clear->rect.ui[CLEAR_Y2] );
-                       OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
 
-                       OUT_RING( clear->rect.ui[CLEAR_X2] );
-                       OUT_RING( clear->rect.ui[CLEAR_Y2] );
-                       OUT_RING( clear->rect.ui[CLEAR_DEPTH] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+                       OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
 
                        ADVANCE_RING();
 
@@ -655,8 +654,6 @@ static void radeon_cp_dispatch_swap( drm_device_t *dev )
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       radeon_update_ring_snapshot( dev_priv );
-
 #if RADEON_PERFORMANCE_BOXES
        /* Do some trivial performance monitoring...
         */
@@ -724,8 +721,6 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
        RING_LOCALS;
        DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
 
-       radeon_update_ring_snapshot( dev_priv );
-
 #if RADEON_PERFORMANCE_BOXES
        /* Do some trivial performance monitoring...
         */
@@ -776,8 +771,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
        RING_LOCALS;
        DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox );
 
-       radeon_update_ring_snapshot( dev_priv );
-
        if ( 0 )
                radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty );
 
@@ -844,8 +837,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
        DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
                   buf->idx, start, end );
 
-       radeon_update_ring_snapshot( dev_priv );
-
        if ( start != end ) {
                int offset = (dev_priv->agp_buffers_offset
                              + buf->offset + start);
@@ -908,8 +899,6 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
        RING_LOCALS;
        DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
 
-       radeon_update_ring_snapshot( dev_priv );
-
        if ( 0 )
                radeon_print_dirty( "dispatch_indices", sarea_priv->dirty );
 
@@ -971,50 +960,67 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
        sarea_priv->nbox = 0;
 }
 
-static int radeon_cp_dispatch_blit( drm_device_t *dev,
-                                   drm_radeon_blit_t *blit )
+#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
+
+static int radeon_cp_dispatch_texture( drm_device_t *dev,
+                                      drm_radeon_texture_t *tex,
+                                      drm_radeon_tex_image_t *image )
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_device_dma_t *dma = dev->dma;
        drm_buf_t *buf;
        drm_radeon_buf_priv_t *buf_priv;
        u32 format;
-       u32 *data;
-       int dword_shift, dwords;
+       u32 *buffer;
+       u8 *data;
+       int size, dwords, tex_width, blit_width;
+       u32 y, height;
+       int ret = 0, i;
        RING_LOCALS;
-       DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
-                  blit->offset >> 10, blit->pitch, blit->format,
-                  blit->x, blit->y, blit->width, blit->height );
 
-       radeon_update_ring_snapshot( dev_priv );
+       /* FIXME: Be smarter about this...
+        */
+       buf = radeon_freelist_get( dev );
+       if ( !buf ) return -EAGAIN;
+
+       DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
+                  tex->offset >> 10, tex->pitch, tex->format,
+                  image->x, image->y, image->width, image->height );
+
+       buf_priv = buf->dev_private;
 
        /* The compiler won't optimize away a division by a variable,
         * even if the only legal values are powers of two.  Thus, we'll
         * use a shift instead.
         */
-       switch ( blit->format ) {
-       case RADEON_TXF_32BPP_ARGB8888:
-       case RADEON_TXF_32BPP_RGBA8888:
+       switch ( tex->format ) {
+       case RADEON_TXFORMAT_ARGB8888:
+       case RADEON_TXFORMAT_RGBA8888:
                format = RADEON_COLOR_FORMAT_ARGB8888;
-               dword_shift = 0;
+               tex_width = tex->width * 4;
+               blit_width = image->width * 4;
                break;
-       case RADEON_TXF_16BPP_AI88:
-       case RADEON_TXF_16BPP_ARGB1555:
-       case RADEON_TXF_16BPP_RGB565:
-       case RADEON_TXF_16BPP_ARGB4444:
+       case RADEON_TXFORMAT_AI88:
+       case RADEON_TXFORMAT_ARGB1555:
+       case RADEON_TXFORMAT_RGB565:
+       case RADEON_TXFORMAT_ARGB4444:
                format = RADEON_COLOR_FORMAT_RGB565;
-               dword_shift = 1;
+               tex_width = tex->width * 2;
+               blit_width = image->width * 2;
                break;
-       case RADEON_TXF_8BPP_I:
-       case RADEON_TXF_8BPP_RGB332:
+       case RADEON_TXFORMAT_I8:
+       case RADEON_TXFORMAT_RGB332:
                format = RADEON_COLOR_FORMAT_CI8;
-               dword_shift = 2;
+               tex_width = tex->width * 1;
+               blit_width = image->width * 1;
                break;
        default:
-               DRM_ERROR( "invalid blit format %d\n", blit->format );
+               DRM_ERROR( "invalid texture format %d\n", tex->format );
                return -EINVAL;
        }
 
+       DRM_DEBUG( "   tex=%dx%d  blit=%d\n",
+                  tex_width, tex->height, blit_width );
+
        /* Flush the pixel cache.  This ensures no pixel data gets mixed
         * up with the texture data from the host data blit, otherwise
         * part of the texture image may be corrupted.
@@ -1026,46 +1032,88 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
 
        ADVANCE_RING();
 
-       /* Dispatch the indirect buffer.
+       /* Make a copy of the parameters in case we have to update them
+        * for a multi-pass texture blit.
         */
-       buf = dma->buflist[blit->idx];
-       buf_priv = buf->dev_private;
+       y = image->y;
+       height = image->height;
+       data = (u8 *)image->data;
 
-       if ( buf->pid != current->pid ) {
-               DRM_ERROR( "process %d using buffer owned by %d\n",
-                          current->pid, buf->pid );
-               return -EINVAL;
-       }
-       if ( buf->pending ) {
-               DRM_ERROR( "sending pending buffer %d\n", blit->idx );
-               return -EINVAL;
-       }
+       size = height * blit_width;
 
-       buf_priv->discard = 1;
+       if ( size > RADEON_MAX_TEXTURE_SIZE ) {
+               /* Texture image is too large, do a multipass upload */
+               ret = -EAGAIN;
 
-       dwords = (blit->width * blit->height) >> dword_shift;
-       if ( !dwords ) dwords = 1;
+               /* Adjust the blit size to fit the indirect buffer */
+               height = RADEON_MAX_TEXTURE_SIZE / blit_width;
+               size = height * blit_width;
 
-       data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+               /* Update the input parameters for next time */
+               image->y += height;
+               image->height -= height;
+               image->data = (char *)image->data + size;
 
-       data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
-       data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
-                  RADEON_GMC_BRUSH_NONE |
-                  (format << 8) |
-                  RADEON_GMC_SRC_DATATYPE_COLOR |
-                  RADEON_ROP3_S |
-                  RADEON_DP_SRC_SOURCE_HOST_DATA |
-                  RADEON_GMC_CLR_CMP_CNTL_DIS |
-                  RADEON_GMC_WR_MSK_DIS);
+               if ( copy_to_user( tex->image, image, sizeof(*image) ) ) {
+                       DRM_ERROR( "EFAULT on tex->image\n" );
+                       return -EFAULT;
+               }
+       } else if ( size < 4 ) {
+               size = 4;
+       }
 
-       data[2] = (blit->pitch << 22) | (blit->offset >> 10);
-       data[3] = 0xffffffff;
-       data[4] = 0xffffffff;
-       data[5] = (blit->y << 16) | blit->x;
-       data[6] = (blit->height << 16) | blit->width;
-       data[7] = dwords;
+       dwords = size / 4;
+
+       /* Dispatch the indirect buffer.
+        */
+       buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
+
+       buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
+       buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+                    RADEON_GMC_BRUSH_NONE |
+                    (format << 8) |
+                    RADEON_GMC_SRC_DATATYPE_COLOR |
+                    RADEON_ROP3_S |
+                    RADEON_DP_SRC_SOURCE_HOST_DATA |
+                    RADEON_GMC_CLR_CMP_CNTL_DIS |
+                    RADEON_GMC_WR_MSK_DIS);
+
+       buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
+       buffer[3] = 0xffffffff;
+       buffer[4] = 0xffffffff;
+       buffer[5] = (y << 16) | image->x;
+       buffer[6] = (height << 16) | image->width;
+       buffer[7] = dwords;
+
+       buffer += 8;
+
+       if ( tex_width >= 32 ) {
+               /* Texture image width is larger than the minimum, so we
+                * can upload it directly.
+                */
+               if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) {
+                       DRM_ERROR( "EFAULT on data, %d dwords\n", dwords );
+                       return -EFAULT;
+               }
+       } else {
+               /* Texture image width is less than the minimum, so we
+                * need to pad out each image scanline to the minimum
+                * width.
+                */
+               for ( i = 0 ; i < tex->height ; i++ ) {
+                       if ( copy_from_user( buffer, data, tex_width ) ) {
+                               DRM_ERROR( "EFAULT on pad, %d bytes\n",
+                                          tex_width );
+                               return -EFAULT;
+                       }
+                       buffer += 8;
+                       data += tex_width;
+               }
+       }
 
+       buf->pid = current->pid;
        buf->used = (dwords + 8) * sizeof(u32);
+       buf_priv->discard = 1;
 
        radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
 
@@ -1080,7 +1128,7 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
 
        ADVANCE_RING();
 
-       return 0;
+       return ret;
 }
 
 static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
@@ -1090,8 +1138,6 @@ static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple )
        RING_LOCALS;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       radeon_update_ring_snapshot( dev_priv );
-
        BEGIN_RING( 35 );
 
        OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) );
@@ -1118,22 +1164,25 @@ int radeon_cp_clear( struct inode *inode, struct file *filp,
        drm_radeon_private_t *dev_priv = dev->dev_private;
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
        drm_radeon_clear_t clear;
+       drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if ( copy_from_user( &clear, (drm_radeon_clear_t *) arg,
+       if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg,
                             sizeof(clear) ) )
                return -EFAULT;
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
        if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-       radeon_cp_dispatch_clear( dev, &clear );
+       if ( copy_from_user( &depth_boxes, clear.depth_boxes,
+                            sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
+               return -EFAULT;
+
+       radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
 
        return 0;
 }
@@ -1147,11 +1196,9 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
        drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
        DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
+
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
        if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
                sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
@@ -1178,13 +1225,10 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
        drm_radeon_buf_priv_t *buf_priv;
        drm_radeon_vertex_t vertex;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-       if ( !dev_priv || dev_priv->is_pci ) {
-               DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
                return -EINVAL;
        }
 
@@ -1207,7 +1251,8 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
-       VB_AGE_CHECK_WITH_RET( dev_priv );
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
 
        buf = dma->buflist[vertex.idx];
        buf_priv = buf->dev_private;
@@ -1243,13 +1288,10 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
        drm_radeon_indices_t elts;
        int count;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-       if ( !dev_priv || dev_priv->is_pci ) {
-               DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
                return -EINVAL;
        }
 
@@ -1272,7 +1314,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
-       VB_AGE_CHECK_WITH_RET( dev_priv );
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
 
        buf = dma->buflist[elts.idx];
        buf_priv = buf->dev_private;
@@ -1308,37 +1351,34 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
        return 0;
 }
 
-int radeon_cp_blit( struct inode *inode, struct file *filp,
-                   unsigned int cmd, unsigned long arg )
+int radeon_cp_texture( struct inode *inode, struct file *filp,
+                      unsigned int cmd, unsigned long arg )
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       drm_device_dma_t *dma = dev->dma;
-       drm_radeon_blit_t blit;
+       drm_radeon_texture_t tex;
+       drm_radeon_tex_image_t image;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg,
-                            sizeof(blit) ) )
+       if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) )
                return -EFAULT;
 
-       DRM_DEBUG( "%s: pid=%d index=%d\n",
-                  __FUNCTION__, current->pid, blit.idx );
-
-       if ( blit.idx < 0 || blit.idx > dma->buf_count ) {
-               DRM_ERROR( "sending %d buffers (of %d max)\n",
-                          blit.idx, dma->buf_count );
+       if ( tex.image == NULL ) {
+               DRM_ERROR( "null texture image!\n" );
                return -EINVAL;
        }
 
-       VB_AGE_CHECK_WITH_RET( dev_priv );
+       if ( copy_from_user( &image,
+                            (drm_radeon_tex_image_t *)tex.image,
+                            sizeof(image) ) )
+               return -EFAULT;
+
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
 
-       return radeon_cp_dispatch_blit( dev, &blit );
+       return radeon_cp_dispatch_texture( dev, &tex, &image );
 }
 
 int radeon_cp_stipple( struct inode *inode, struct file *filp,
@@ -1346,23 +1386,21 @@ int radeon_cp_stipple( struct inode *inode, struct file *filp,
 {
        drm_file_t *priv = filp->private_data;
        drm_device_t *dev = priv->dev;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
        drm_radeon_stipple_t stipple;
        u32 mask[32];
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
+       LOCK_TEST_WITH_RETURN( dev );
 
        if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
                             sizeof(stipple) ) )
                return -EFAULT;
 
-       if ( copy_from_user( &mask, stipple.mask,
-                            32 * sizeof(u32) ) )
+       if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) )
                return -EFAULT;
 
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
        radeon_cp_dispatch_stipple( dev, mask );
 
        return 0;
@@ -1380,13 +1418,10 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
        drm_radeon_indirect_t indirect;
        RING_LOCALS;
 
-       if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
-            dev->lock.pid != current->pid ) {
-               DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
-               return -EINVAL;
-       }
-       if ( !dev_priv || dev_priv->is_pci ) {
-               DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
+       LOCK_TEST_WITH_RETURN( dev );
+
+       if ( !dev_priv ) {
+               DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
                return -EINVAL;
        }
 
@@ -1423,7 +1458,8 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
                return -EINVAL;
        }
 
-       VB_AGE_CHECK_WITH_RET( dev_priv );
+       RING_SPACE_TEST_WITH_RETURN( dev_priv );
+       VB_AGE_TEST_WITH_RETURN( dev_priv );
 
        buf->used = indirect.end;
        buf_priv->discard = indirect.discard;
diff --git a/drivers/char/drm/tdfx.h b/drivers/char/drm/tdfx.h
new file mode 100644 (file)
index 0000000..40aba8f
--- /dev/null
@@ -0,0 +1,42 @@
+/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
+ * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __TDFX_H__
+#define __TDFX_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) tdfx_##x
+
+/* General customization:
+ */
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+
+#endif
diff --git a/drivers/char/drm/tdfx_context.c b/drivers/char/drm/tdfx_context.c
deleted file mode 100644 (file)
index 1fd7331..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/* tdfx_context.c -- IOCTLs for tdfx contexts -*- linux-c -*-
- * Created: Thu Oct  7 10:50:22 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *    Daryll Strauss <daryll@valinux.com>
- * 
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-#include "tdfx_drv.h"
-
-extern drm_ctx_t tdfx_res_ctx;
-
-static int tdfx_alloc_queue(drm_device_t *dev)
-{
-       return drm_ctxbitmap_next(dev);
-}
-
-int tdfx_context_switch(drm_device_t *dev, int old, int new)
-{
-        char        buf[64];
-
-        atomic_inc(&dev->total_ctx);
-
-        if (test_and_set_bit(0, &dev->context_flag)) {
-                DRM_ERROR("Reentering -- FIXME\n");
-                return -EBUSY;
-        }
-
-#if DRM_DMA_HISTOGRAM
-        dev->ctx_start = get_cycles();
-#endif
-        
-        DRM_DEBUG("Context switch from %d to %d\n", old, new);
-
-        if (new == dev->last_context) {
-                clear_bit(0, &dev->context_flag);
-                return 0;
-        }
-        
-        if (drm_flags & DRM_FLAG_NOCTX) {
-                tdfx_context_switch_complete(dev, new);
-        } else {
-                sprintf(buf, "C %d %d\n", old, new);
-                drm_write_string(dev, buf);
-        }
-        
-        return 0;
-}
-
-int tdfx_context_switch_complete(drm_device_t *dev, int new)
-{
-        dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
-        dev->last_switch  = jiffies;
-        
-        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. */
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
-                                                      - dev->ctx_start)]);
-                   
-#endif
-        clear_bit(0, &dev->context_flag);
-        wake_up(&dev->context_wait);
-        
-        return 0;
-}
-
-
-int tdfx_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_ctx_res_t   res;
-       drm_ctx_t       ctx;
-       int             i;
-
-       DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
-       if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
-               return -EFAULT;
-       if (res.count >= DRM_RESERVED_CONTEXTS) {
-               memset(&ctx, 0, sizeof(ctx));
-               for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
-                       ctx.handle = i;
-                       if (copy_to_user(&res.contexts[i],
-                                        &i,
-                                        sizeof(i)))
-                               return -EFAULT;
-               }
-       }
-       res.count = DRM_RESERVED_CONTEXTS;
-       if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res)))
-               return -EFAULT;
-       return 0;
-}
-
-
-int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       if ((ctx.handle = tdfx_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
-                               /* Skip kernel's context and get a new one. */
-               ctx.handle = tdfx_alloc_queue(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 (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int tdfx_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       if (ctx.flags==_DRM_CONTEXT_PRESERVED)
-               tdfx_res_ctx.handle=ctx.handle;
-       return 0;
-}
-
-int tdfx_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
-       unsigned long arg)
-{
-       drm_ctx_t ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx)))
-               return -EFAULT;
-       /* This is 0, because we don't handle any context flags */
-       ctx.flags = 0;
-       if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx)))
-               return -EFAULT;
-       return 0;
-}
-
-int tdfx_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       return tdfx_context_switch(dev, dev->last_context, ctx.handle);
-}
-
-int tdfx_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       tdfx_context_switch_complete(dev, ctx.handle);
-
-       return 0;
-}
-
-int tdfx_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_ctx_t       ctx;
-
-       if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
-               return -EFAULT;
-       DRM_DEBUG("%d\n", ctx.handle);
-       drm_ctxbitmap_free(dev, ctx.handle);
-
-       return 0;
-}
index 7d79a013b7bb75674d7a32fa1e8bc72794f3c6fa..8f9758752c4fa8da1982ae27150ab696f74bfc2e 100644 (file)
  * Authors:
  *    Rickard E. (Rik) Faith <faith@valinux.com>
  *    Daryll Strauss <daryll@valinux.com>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #include <linux/config.h>
+#include "tdfx.h"
 #include "drmP.h"
-#include "tdfx_drv.h"
 
-#define TDFX_NAME       "tdfx"
-#define TDFX_DESC       "3dfx Banshee/Voodoo3+"
-#define TDFX_DATE       "20000928"
-#define TDFX_MAJOR      1
-#define TDFX_MINOR      0
-#define TDFX_PATCHLEVEL  0
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "tdfx"
+#define DRIVER_DESC            "3dfx Banshee/Voodoo3+"
+#define DRIVER_DATE            "20010216"
 
-static drm_device_t          tdfx_device;
-drm_ctx_t                    tdfx_res_ctx;
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
 
-static struct file_operations tdfx_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO5
+#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
 #endif
-       open:    tdfx_open,
-       flush:   drm_flush,
-       release: tdfx_release,
-       ioctl:   tdfx_ioctl,
-       mmap:    drm_mmap,
-       read:    drm_read,
-       fasync:  drm_fasync,
-       poll:    drm_poll,
-};
 
-static struct miscdevice      tdfx_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  TDFX_NAME,
-       fops:  &tdfx_fops,
+static drm_pci_list_t DRM(idlist)[] = {
+       { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE },
+       { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3 },
+       { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5 },
+       { 0, 0 }
 };
 
-static drm_ioctl_desc_t              tdfx_ioctls[] = {
-       [DRM_IOCTL_NR(DRM_IOCTL_VERSION)]    = { tdfx_version,    0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique,   0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]  = { drm_getmagic,    0, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]  = { drm_irq_busid,   0, 1 },
-
-       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]      = { drm_block,       1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]    = { drm_unblock,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic,   1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]    = { drm_addmap,      1, 1 },
+#define DRIVER_CARD_LIST DRM(idlist)
 
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]    = { tdfx_addctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]     = { tdfx_rmctx,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]    = { tdfx_modctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]    = { tdfx_getctx,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { tdfx_switchctx,  1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]    = { tdfx_newctx,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]    = { tdfx_resctx,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]   = { drm_adddraw,     1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]    = { drm_rmdraw,      1, 1 },
-       [DRM_IOCTL_NR(DRM_IOCTL_LOCK)]       = { tdfx_lock,       1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]     = { tdfx_unlock,     1, 0 },
-       [DRM_IOCTL_NR(DRM_IOCTL_FINISH)]     = { drm_finish,      1, 0 },
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = {drm_agp_acquire, 1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = {drm_agp_release, 1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = {drm_agp_enable,  1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = {drm_agp_info,    1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = {drm_agp_alloc,   1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = {drm_agp_free,    1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = {drm_agp_unbind,  1, 1},
-       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = {drm_agp_bind,    1, 1},
-#endif
-};
-#define TDFX_IOCTL_COUNT DRM_ARRAY_SIZE(tdfx_ioctls)
-
-#ifdef MODULE
-static char                  *tdfx = NULL;
-#endif
 
-MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("tdfx");
-MODULE_PARM(tdfx, "s");
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
 
 #ifndef MODULE
-/* tdfx_options is called by the kernel to parse command-line options
+/* DRM(options) is called by the kernel to parse command-line options
  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
  * routine, drm_parse_drm.
  */
 
-static int __init tdfx_options(char *str)
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init tdfx_options( char *str )
 {
-       drm_parse_options(str);
+       DRM(parse_options)( str );
        return 1;
 }
 
-__setup("tdfx=", tdfx_options);
-#endif
-
-static int tdfx_setup(drm_device_t *dev)
-{
-       int i;
-
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       dev->buf_use      = 0;
-       atomic_set(&dev->buf_alloc, 0);
-
-       atomic_set(&dev->total_open, 0);
-       atomic_set(&dev->total_close, 0);
-       atomic_set(&dev->total_ioctl, 0);
-       atomic_set(&dev->total_irq, 0);
-       atomic_set(&dev->total_ctx, 0);
-       atomic_set(&dev->total_locks, 0);
-       atomic_set(&dev->total_unlocks, 0);
-       atomic_set(&dev->total_contends, 0);
-       atomic_set(&dev->total_sleeps, 0);
-
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               dev->magiclist[i].head = NULL;
-               dev->magiclist[i].tail = NULL;
-       }
-       dev->maplist        = NULL;
-       dev->map_count      = 0;
-       dev->vmalist        = NULL;
-       dev->lock.hw_lock   = NULL;
-       init_waitqueue_head(&dev->lock.lock_queue);
-       dev->queue_count    = 0;
-       dev->queue_reserved = 0;
-       dev->queue_slots    = 0;
-       dev->queuelist      = NULL;
-       dev->irq            = 0;
-       dev->context_flag   = 0;
-       dev->interrupt_flag = 0;
-       dev->dma            = 0;
-       dev->dma_flag       = 0;
-       dev->last_context   = 0;
-       dev->last_switch    = 0;
-       dev->last_checked   = 0;
-       init_timer(&dev->timer);
-       init_waitqueue_head(&dev->context_wait);
-
-       dev->ctx_start      = 0;
-       dev->lck_start      = 0;
-
-       dev->buf_rp       = dev->buf;
-       dev->buf_wp       = dev->buf;
-       dev->buf_end      = dev->buf + DRM_BSZ;
-       dev->buf_async    = NULL;
-       init_waitqueue_head(&dev->buf_readers);
-       init_waitqueue_head(&dev->buf_writers);
-
-       tdfx_res_ctx.handle=-1;
-
-       DRM_DEBUG("\n");
-
-       /* The kernel's context could be created here, but is now created
-          in drm_dma_enqueue.  This is more resource-efficient for
-          hardware that does not do DMA, but may mean that
-          drm_select_queue fails between the time the interrupt is
-          initialized and the time the queues are initialized. */
-
-       return 0;
-}
-
-
-static int tdfx_takedown(drm_device_t *dev)
-{
-       int               i;
-       drm_magic_entry_t *pt, *next;
-       drm_map_t         *map;
-       drm_vma_entry_t   *vma, *vma_next;
-
-       DRM_DEBUG("\n");
-
-       down(&dev->struct_sem);
-       del_timer(&dev->timer);
-
-       if (dev->devname) {
-               drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
-               dev->devname = NULL;
-       }
-
-       if (dev->unique) {
-               drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
-               dev->unique = NULL;
-               dev->unique_len = 0;
-       }
-                               /* Clear pid list */
-       for (i = 0; i < DRM_HASH_SIZE; i++) {
-               for (pt = dev->magiclist[i].head; pt; pt = next) {
-                       next = pt->next;
-                       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-               }
-               dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
-       }
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-                               /* Clear AGP information */
-       if (dev->agp) {
-               drm_agp_mem_t *temp;
-               drm_agp_mem_t *temp_next;
-
-               temp = dev->agp->memory;
-               while(temp != NULL) {
-                       temp_next = temp->next;
-                       drm_free_agp(temp->memory, temp->pages);
-                       drm_free(temp, sizeof(*temp), DRM_MEM_AGPLISTS);
-                       temp = temp_next;
-               }
-               if (dev->agp->acquired) _drm_agp_release();
-       }
-#endif
-                               /* Clear vma list (only built for debugging) */
-       if (dev->vmalist) {
-               for (vma = dev->vmalist; vma; vma = vma_next) {
-                       vma_next = vma->next;
-                       drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
-               }
-               dev->vmalist = NULL;
-       }
-
-                               /* Clear map area and mtrr information */
-       if (dev->maplist) {
-               for (i = 0; i < dev->map_count; i++) {
-                       map = dev->maplist[i];
-                       switch (map->type) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
-#ifdef CONFIG_MTRR
-                               if (map->mtrr >= 0) {
-                                       int retcode;
-                                       retcode = mtrr_del(map->mtrr,
-                                                          map->offset,
-                                                          map->size);
-                                       DRM_DEBUG("mtrr_del = %d\n", retcode);
-                               }
-#endif
-                               drm_ioremapfree(map->handle, map->size);
-                               break;
-                       case _DRM_SHM:
-                               drm_free_pages((unsigned long)map->handle,
-                                              drm_order(map->size)
-                                              - PAGE_SHIFT,
-                                              DRM_MEM_SAREA);
-                               break;
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                   handled in the AGP/GART driver. */
-                               break;
-                       }
-                       drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-               }
-               drm_free(dev->maplist,
-                        dev->map_count * sizeof(*dev->maplist),
-                        DRM_MEM_MAPS);
-               dev->maplist   = NULL;
-               dev->map_count = 0;
-       }
-
-       if (dev->lock.hw_lock) {
-               dev->lock.hw_lock    = NULL; /* SHM removed */
-               dev->lock.pid        = 0;
-               wake_up_interruptible(&dev->lock.lock_queue);
-       }
-       up(&dev->struct_sem);
-
-       return 0;
-}
-
-/* tdfx_init is called via init_module at module load time, or via
- * linux/init/main.c (this is not currently supported). */
-
-static int __init tdfx_init(void)
-{
-       int                   retcode;
-       drm_device_t          *dev = &tdfx_device;
-
-       DRM_DEBUG("\n");
-
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->count_lock   = SPIN_LOCK_UNLOCKED;
-       sema_init(&dev->struct_sem, 1);
-
-#ifdef MODULE
-       drm_parse_options(tdfx);
-#endif
-
-       if ((retcode = misc_register(&tdfx_misc))) {
-               DRM_ERROR("Cannot register \"%s\"\n", TDFX_NAME);
-               return retcode;
-       }
-       dev->device = MKDEV(MISC_MAJOR, tdfx_misc.minor);
-       dev->name   = TDFX_NAME;
-
-       drm_mem_init();
-       drm_proc_init(dev);
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       dev->agp    = drm_agp_init();
-#endif
-       if((retcode = drm_ctxbitmap_init(dev))) {
-               DRM_ERROR("Cannot allocate memory for context bitmap.\n");
-               drm_proc_cleanup();
-               misc_deregister(&tdfx_misc);
-               tdfx_takedown(dev);
-               return retcode;
-       }
-
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
-                TDFX_NAME,
-                TDFX_MAJOR,
-                TDFX_MINOR,
-                TDFX_PATCHLEVEL,
-                TDFX_DATE,
-                tdfx_misc.minor);
-
-       return 0;
-}
-
-/* tdfx_cleanup is called via cleanup_module at module unload time. */
-
-static void __exit tdfx_cleanup(void)
-{
-       drm_device_t          *dev = &tdfx_device;
-
-       DRM_DEBUG("\n");
-
-       drm_proc_cleanup();
-       if (misc_deregister(&tdfx_misc)) {
-               DRM_ERROR("Cannot unload module\n");
-       } else {
-               DRM_INFO("Module unloaded\n");
-       }
-       drm_ctxbitmap_cleanup(dev);
-       tdfx_takedown(dev);
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-       if (dev->agp) {
-               drm_agp_uninit();
-               drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
-               dev->agp = NULL;
-       }
-#endif
-}
-
-module_init(tdfx_init);
-module_exit(tdfx_cleanup);
-
-
-int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
-{
-       drm_version_t version;
-       int           len;
-
-       if (copy_from_user(&version,
-                          (drm_version_t *)arg,
-                          sizeof(version)))
-               return -EFAULT;
-
-#define DRM_COPY(name,value)                                \
-       len = strlen(value);                                 \
-       if (len > name##_len) len = name##_len;              \
-       name##_len = strlen(value);                          \
-       if (len && name) {                                   \
-               if (copy_to_user(name, value, len))          \
-                       return -EFAULT;                      \
-       }
-
-       version.version_major      = TDFX_MAJOR;
-       version.version_minor      = TDFX_MINOR;
-       version.version_patchlevel = TDFX_PATCHLEVEL;
-
-       DRM_COPY(version.name, TDFX_NAME);
-       DRM_COPY(version.date, TDFX_DATE);
-       DRM_COPY(version.desc, TDFX_DESC);
-
-       if (copy_to_user((drm_version_t *)arg,
-                        &version,
-                        sizeof(version)))
-               return -EFAULT;
-       return 0;
-}
-
-int tdfx_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t  *dev    = &tdfx_device;
-       int           retcode = 0;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_open_helper(inode, filp, dev))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_open);
-               spin_lock(&dev->count_lock);
-               if (!dev->open_count++) {
-                       spin_unlock(&dev->count_lock);
-                       return tdfx_setup(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-       return retcode;
-}
-
-int tdfx_release(struct inode *inode, struct file *filp)
-{
-       drm_file_t    *priv   = filp->private_data;
-       drm_device_t  *dev;
-       int           retcode = 0;
-
-       lock_kernel();
-       dev = priv->dev;
-
-       DRM_DEBUG("open_count = %d\n", dev->open_count);
-       if (!(retcode = drm_release(inode, filp))) {
-#if LINUX_VERSION_CODE < 0x020333
-               MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-               atomic_inc(&dev->total_close);
-               spin_lock(&dev->count_lock);
-               if (!--dev->open_count) {
-                       if (atomic_read(&dev->ioctl_count) || dev->blocked) {
-                               DRM_ERROR("Device busy: %d %d\n",
-                                         atomic_read(&dev->ioctl_count),
-                                         dev->blocked);
-                               spin_unlock(&dev->count_lock);
-                               unlock_kernel();
-                               return -EBUSY;
-                       }
-                       spin_unlock(&dev->count_lock);
-                       unlock_kernel();
-                       return tdfx_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return retcode;
-}
-
-/* tdfx_ioctl is called whenever a process performs an ioctl on /dev/drm. */
-
-int tdfx_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
-{
-       int              nr      = DRM_IOCTL_NR(cmd);
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev    = priv->dev;
-       int              retcode = 0;
-       drm_ioctl_desc_t *ioctl;
-       drm_ioctl_t      *func;
-
-       atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->total_ioctl);
-       ++priv->ioctl_count;
-
-       DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
-                 current->pid, cmd, nr, dev->device, priv->authenticated);
-
-       if (nr >= TDFX_IOCTL_COUNT) {
-               retcode = -EINVAL;
-       } else {
-               ioctl     = &tdfx_ioctls[nr];
-               func      = ioctl->func;
-
-               if (!func) {
-                       DRM_DEBUG("no function\n");
-                       retcode = -EINVAL;
-               } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
-                           || (ioctl->auth_needed && !priv->authenticated)) {
-                       retcode = -EACCES;
-               } else {
-                       retcode = (func)(inode, filp, cmd, arg);
-               }
-       }
-
-       atomic_dec(&dev->ioctl_count);
-       return retcode;
-}
-
-int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
-{
-        drm_file_t        *priv   = filp->private_data;
-        drm_device_t      *dev    = priv->dev;
-        DECLARE_WAITQUEUE(entry, current);
-        int               ret   = 0;
-        drm_lock_t        lock;
-#if DRM_DMA_HISTOGRAM
-        cycles_t          start;
-
-        dev->lck_start = start = get_cycles();
-#endif
-
-        if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-        if (lock.context == DRM_KERNEL_CONTEXT) {
-                DRM_ERROR("Process %d using kernel context %d\n",
-                          current->pid, lock.context);
-                return -EINVAL;
-        }
-
-        DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
-                  lock.context, current->pid, dev->lock.hw_lock->lock,
-                  lock.flags);
-
-#if 0
-                               /* dev->queue_count == 0 right now for
-                                   tdfx.  FIXME? */
-        if (lock.context < 0 || lock.context >= dev->queue_count)
-                return -EINVAL;
-#endif
-
-        if (!ret) {
-#if 0
-                if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
-                    != lock.context) {
-                        long j = jiffies - dev->lock.lock_time;
-
-                        if (lock.context == tdfx_res_ctx.handle &&
-                               j >= 0 && j < DRM_LOCK_SLICE) {
-                                /* Can't take lock if we just had it and
-                                   there is contention. */
-                                DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
-                                       lock.context, current->pid, j,
-                                       dev->lock.lock_time, jiffies);
-                                current->state = TASK_INTERRUPTIBLE;
-                               current->policy |= SCHED_YIELD;
-                                schedule_timeout(DRM_LOCK_SLICE-j);
-                               DRM_DEBUG("jiffies=%d\n", jiffies);
-                        }
-                }
-#endif
-                add_wait_queue(&dev->lock.lock_queue, &entry);
-                for (;;) {
-                        current->state = TASK_INTERRUPTIBLE;
-                        if (!dev->lock.hw_lock) {
-                                /* Device has been unregistered */
-                                ret = -EINTR;
-                                break;
-                        }
-                        if (drm_lock_take(&dev->lock.hw_lock->lock,
-                                          lock.context)) {
-                                dev->lock.pid       = current->pid;
-                                dev->lock.lock_time = jiffies;
-                                atomic_inc(&dev->total_locks);
-                                break;  /* Got lock */
-                        }
-
-                                /* Contention */
-                        atomic_inc(&dev->total_sleeps);
-#if 1
-                       current->policy |= SCHED_YIELD;
-#endif
-                        schedule();
-                        if (signal_pending(current)) {
-                                ret = -ERESTARTSYS;
-                                break;
-                        }
-                }
-                current->state = TASK_RUNNING;
-                remove_wait_queue(&dev->lock.lock_queue, &entry);
-        }
-
-#if 0
-       if (!ret && dev->last_context != lock.context &&
-               lock.context != tdfx_res_ctx.handle &&
-               dev->last_context != tdfx_res_ctx.handle) {
-               add_wait_queue(&dev->context_wait, &entry);
-               current->state = TASK_INTERRUPTIBLE;
-                /* PRE: dev->last_context != lock.context */
-               tdfx_context_switch(dev, dev->last_context, lock.context);
-               /* POST: we will wait for the context
-                   switch and will dispatch on a later call
-                   when dev->last_context == lock.context
-                   NOTE WE HOLD THE LOCK THROUGHOUT THIS
-                   TIME! */
-               current->policy |= SCHED_YIELD;
-               schedule();
-               current->state = TASK_RUNNING;
-               remove_wait_queue(&dev->context_wait, &entry);
-               if (signal_pending(current)) {
-                       ret = -EINTR;
-               } else if (dev->last_context != lock.context) {
-                       DRM_ERROR("Context mismatch: %d %d\n",
-                               dev->last_context, lock.context);
-               }
-       }
-#endif
-
-        if (!ret) {
-               sigemptyset(&dev->sigmask);
-               sigaddset(&dev->sigmask, SIGSTOP);
-               sigaddset(&dev->sigmask, SIGTSTP);
-               sigaddset(&dev->sigmask, SIGTTIN);
-               sigaddset(&dev->sigmask, SIGTTOU);
-               dev->sigdata.context = lock.context;
-               dev->sigdata.lock    = dev->lock.hw_lock;
-               block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
-
-                if (lock.flags & _DRM_LOCK_READY) {
-                               /* Wait for space in DMA/FIFO */
-               }
-                if (lock.flags & _DRM_LOCK_QUIESCENT) {
-                               /* Make hardware quiescent */
-#if 0
-                        tdfx_quiescent(dev);
-#endif
-               }
-        }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != tdfx_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY/4;
-       }
-#endif
-        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
-
-#if DRM_DMA_HISTOGRAM
-        atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
-#endif
-
-        return ret;
-}
-
-
-int tdfx_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
-{
-       drm_file_t        *priv   = filp->private_data;
-       drm_device_t      *dev    = priv->dev;
-       drm_lock_t        lock;
-
-       if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
-               return -EFAULT;
-
-       if (lock.context == DRM_KERNEL_CONTEXT) {
-               DRM_ERROR("Process %d using kernel context %d\n",
-                         current->pid, lock.context);
-               return -EINVAL;
-       }
-
-       DRM_DEBUG("%d frees lock (%d holds)\n",
-                 lock.context,
-                 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-       atomic_inc(&dev->total_unlocks);
-       if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
-               atomic_inc(&dev->total_contends);
-       drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
-                               /* FIXME: Try to send data to card here */
-       if (!dev->context_flag) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
-
-#if LINUX_VERSION_CODE < 0x020400
-       if (lock.context != tdfx_res_ctx.handle) {
-               current->counter = 5;
-               current->priority = DEF_PRIORITY;
-       }
+__setup( DRIVER_NAME "=", tdfx_options );
 #endif
 
-       unblock_all_signals();
-       return 0;
-}
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
deleted file mode 100644 (file)
index bee840e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* tdfx_drv.h -- Private header for tdfx driver -*- linux-c -*-
- * Created: Thu Oct  7 10:40:04 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *    Daryll Strauss <daryll@valinux.com>
- * 
- */
-
-#ifndef _TDFX_DRV_H_
-#define _TDFX_DRV_H_
-
-                               /* tdfx_drv.c */
-extern int  tdfx_version(struct inode *inode, struct file *filp,
-                         unsigned int cmd, unsigned long arg);
-extern int  tdfx_open(struct inode *inode, struct file *filp);
-extern int  tdfx_release(struct inode *inode, struct file *filp);
-extern int  tdfx_ioctl(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_lock(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-extern int  tdfx_unlock(struct inode *inode, struct file *filp,
-                        unsigned int cmd, unsigned long arg);
-
-                               /* tdfx_context.c */
-
-extern int  tdfx_resctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_addctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_modctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_getctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_switchctx(struct inode *inode, struct file *filp,
-                          unsigned int cmd, unsigned long arg);
-extern int  tdfx_newctx(struct inode *inode, struct file *filp,
-                       unsigned int cmd, unsigned long arg);
-extern int  tdfx_rmctx(struct inode *inode, struct file *filp,
-                      unsigned int cmd, unsigned long arg);
-
-extern int  tdfx_context_switch(drm_device_t *dev, int old, int new);
-extern int  tdfx_context_switch_complete(drm_device_t *dev, int new);
-#endif
diff --git a/drivers/char/drm/vm.c b/drivers/char/drm/vm.c
deleted file mode 100644 (file)
index 964921b..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/* vm.c -- Memory mapping for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
- *
- * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
- * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#define __NO_VERSION__
-#include "drmP.h"
-
-struct vm_operations_struct   drm_vm_ops = {
-       nopage:  drm_vm_nopage,
-       open:    drm_vm_open,
-       close:   drm_vm_close,
-};
-
-struct vm_operations_struct   drm_vm_shm_ops = {
-       nopage:  drm_vm_shm_nopage,
-       open:    drm_vm_open,
-       close:   drm_vm_close,
-};
-
-struct vm_operations_struct   drm_vm_shm_lock_ops = {
-       nopage:  drm_vm_shm_nopage_lock,
-       open:    drm_vm_open,
-       close:   drm_vm_close,
-};
-
-struct vm_operations_struct   drm_vm_dma_ops = {
-       nopage:  drm_vm_dma_nopage,
-       open:    drm_vm_open,
-       close:   drm_vm_close,
-};
-
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_nopage(struct vm_area_struct *vma,
-                           unsigned long address,
-                           int write_access)
-#else
-                               /* Return type changed in 2.3.23 */
-struct page *drm_vm_nopage(struct vm_area_struct *vma,
-                          unsigned long address,
-                          int write_access)
-#endif
-{
-       return NOPAGE_SIGBUS;           /* Disallow mremap */
-}
-
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
-                               unsigned long address,
-                               int write_access)
-#else
-                               /* Return type changed in 2.3.23 */
-struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
-                              unsigned long address,
-                              int write_access)
-#endif
-{
-#if LINUX_VERSION_CODE >= 0x020300
-       drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
-#else
-       drm_map_t        *map    = (drm_map_t *)vma->vm_pte;
-#endif
-       unsigned long    physical;
-       unsigned long    offset;
-
-       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-       if (!map)                  return NOPAGE_OOM;  /* Nothing allocated */
-
-       offset   = address - vma->vm_start;
-       physical = (unsigned long)map->handle + offset;
-       atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
-
-       DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
-#if LINUX_VERSION_CODE < 0x020317
-       return physical;
-#else
-       return virt_to_page(physical);
-#endif
-}
-
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
-                                    unsigned long address,
-                                    int write_access)
-#else
-                               /* Return type changed in 2.3.23 */
-struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
-                                   unsigned long address,
-                                   int write_access)
-#endif
-{
-       drm_file_t       *priv   = vma->vm_file->private_data;
-       drm_device_t     *dev    = priv->dev;
-       unsigned long    physical;
-       unsigned long    offset;
-       unsigned long    page;
-
-       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-       if (!dev->lock.hw_lock)    return NOPAGE_OOM;  /* Nothing allocated */
-
-       offset   = address - vma->vm_start;
-       page     = offset >> PAGE_SHIFT;
-       physical = (unsigned long)dev->lock.hw_lock + offset;
-       atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
-
-       DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
-#if LINUX_VERSION_CODE < 0x020317
-       return physical;
-#else
-       return virt_to_page(physical);
-#endif
-}
-
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
-                               unsigned long address,
-                               int write_access)
-#else
-                               /* Return type changed in 2.3.23 */
-struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
-                              unsigned long address,
-                              int write_access)
-#endif
-{
-       drm_file_t       *priv   = vma->vm_file->private_data;
-       drm_device_t     *dev    = priv->dev;
-       drm_device_dma_t *dma    = dev->dma;
-       unsigned long    physical;
-       unsigned long    offset;
-       unsigned long    page;
-
-       if (!dma)                  return NOPAGE_SIGBUS; /* Error */
-       if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
-       if (!dma->pagelist)        return NOPAGE_OOM ; /* Nothing allocated */
-
-       offset   = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
-       page     = offset >> PAGE_SHIFT;
-       physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
-       atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
-
-       DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
-#if LINUX_VERSION_CODE < 0x020317
-       return physical;
-#else
-       return virt_to_page(physical);
-#endif
-}
-
-void drm_vm_open(struct vm_area_struct *vma)
-{
-       drm_file_t      *priv   = vma->vm_file->private_data;
-       drm_device_t    *dev    = priv->dev;
-#if DRM_DEBUG_CODE
-       drm_vma_entry_t *vma_entry;
-#endif
-
-       DRM_DEBUG("0x%08lx,0x%08lx\n",
-                 vma->vm_start, vma->vm_end - vma->vm_start);
-       atomic_inc(&dev->vma_count);
-#if LINUX_VERSION_CODE < 0x020333
-                               /* The map can exist after the fd is closed. */
-       MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-
-
-#if DRM_DEBUG_CODE
-       vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
-       if (vma_entry) {
-               down(&dev->struct_sem);
-               vma_entry->vma  = vma;
-               vma_entry->next = dev->vmalist;
-               vma_entry->pid  = current->pid;
-               dev->vmalist    = vma_entry;
-               up(&dev->struct_sem);
-       }
-#endif
-}
-
-void drm_vm_close(struct vm_area_struct *vma)
-{
-       drm_file_t      *priv   = vma->vm_file->private_data;
-       drm_device_t    *dev    = priv->dev;
-#if DRM_DEBUG_CODE
-       drm_vma_entry_t *pt, *prev;
-#endif
-
-       DRM_DEBUG("0x%08lx,0x%08lx\n",
-                 vma->vm_start, vma->vm_end - vma->vm_start);
-#if LINUX_VERSION_CODE < 0x020333
-       MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
-       atomic_dec(&dev->vma_count);
-
-#if DRM_DEBUG_CODE
-       down(&dev->struct_sem);
-       for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-               if (pt->vma == vma) {
-                       if (prev) {
-                               prev->next = pt->next;
-                       } else {
-                               dev->vmalist = pt->next;
-                       }
-                       drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
-                       break;
-               }
-       }
-       up(&dev->struct_sem);
-#endif
-}
-
-int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
-{
-       drm_file_t       *priv   = filp->private_data;
-       drm_device_t     *dev;
-       drm_device_dma_t *dma;
-       unsigned long    length  = vma->vm_end - vma->vm_start;
-       
-       lock_kernel();
-       dev      = priv->dev;
-       dma      = dev->dma;
-       DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-                 vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-                               /* Length must match exact page count */
-       if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
-               unlock_kernel();
-               return -EINVAL;
-       }
-       unlock_kernel();
-
-       vma->vm_ops   = &drm_vm_dma_ops;
-       vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-       
-#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
-                               /* In Linux 2.2.3 and above, this is
-                                  handled in do_mmap() in mm/mmap.c. */
-       ++filp->f_count;
-#endif
-       vma->vm_file  =  filp;  /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
-       return 0;
-}
-
-int drm_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-       drm_file_t      *priv   = filp->private_data;
-       drm_device_t    *dev    = priv->dev;
-       drm_map_t       *map    = NULL;
-       int             i;
-       
-       DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-                 vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-
-       if (!VM_OFFSET(vma)) return drm_mmap_dma(filp, vma);
-
-                               /* A sequential search of a linked list is
-                                  fine here because: 1) there will only be
-                                  about 5-10 entries in the list and, 2) a
-                                  DRI client only has to do this mapping
-                                  once, so it doesn't have to be optimized
-                                  for performance, even if the list was a
-                                  bit longer. */
-       for (i = 0; i < dev->map_count; i++) {
-               map = dev->maplist[i];
-               if (map->offset == VM_OFFSET(vma)) break;
-       }
-       
-       if (i >= dev->map_count) return -EINVAL;
-       if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
-               return -EPERM;
-
-                               /* Check for valid size. */
-       if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
-       
-       if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
-               vma->vm_flags &= VM_MAYWRITE;
-#if defined(__i386__)
-               pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
-#else
-                               /* Ye gads this is ugly.  With more thought
-                                   we could move this up higher and use
-                                   `protection_map' instead.  */
-               vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
-                       __pte(pgprot_val(vma->vm_page_prot)))));
-#endif
-       }
-
-       switch (map->type) {
-       case _DRM_FRAME_BUFFER:
-       case _DRM_REGISTERS:
-       case _DRM_AGP:
-               if (VM_OFFSET(vma) >= __pa(high_memory)) {
-#if defined(__i386__)
-                       if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
-                               pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
-                               pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
-                       }
-#elif defined(__ia64__)
-                       if (map->type != _DRM_AGP)
-                               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-#endif
-                       vma->vm_flags |= VM_IO; /* not in core dump */
-               }
-               if (remap_page_range(vma->vm_start,
-                                    VM_OFFSET(vma),
-                                    vma->vm_end - vma->vm_start,
-                                    vma->vm_page_prot))
-                               return -EAGAIN;
-               DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
-                         " offset = 0x%lx\n",
-                         map->type,
-                         vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-               vma->vm_ops = &drm_vm_ops;
-               break;
-       case _DRM_SHM:
-               if (map->flags & _DRM_CONTAINS_LOCK)
-                       vma->vm_ops = &drm_vm_shm_lock_ops;
-               else {
-                       vma->vm_ops = &drm_vm_shm_ops;
-#if LINUX_VERSION_CODE >= 0x020300
-                       vma->vm_private_data = (void *)map;
-#else
-                       vma->vm_pte = (unsigned long)map;
-#endif
-               }
-
-                               /* Don't let this area swap.  Change when
-                                  DRM_KERNEL advisory is supported. */
-               vma->vm_flags |= VM_LOCKED;
-               break;
-       default:
-               return -EINVAL; /* This should never happen. */
-       }
-       vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
-
-#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
-                               /* In Linux 2.2.3 and above, this is
-                                  handled in do_mmap() in mm/mmap.c. */
-       ++filp->f_count;
-#endif
-       vma->vm_file  =  filp;  /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
-       return 0;
-}
index 9cc2668d4eef4eda64ff3dbe30e80605acdd4e5c..9e92ffea648d7da5742c80be9c3f711097ed4700 100644 (file)
@@ -231,6 +231,7 @@ static int write_some_buffers(kdev_t dev)
                        return -EAGAIN;
                }
                unlock_buffer(bh);
+               __refile_buffer(bh);
        }
        spin_unlock(&lru_list_lock);
 
@@ -1116,15 +1117,17 @@ void balance_dirty(kdev_t dev)
        /* If we're getting into imbalance, start write-out */
        spin_lock(&lru_list_lock);
        write_some_buffers(dev);
-       wakeup_bdflush();
 
        /*
         * And if we're _really_ out of balance, wait for
-        * some of the dirty/locked buffers ourselves.
+        * some of the dirty/locked buffers ourselves and
+        * start bdflush.
         * This will throttle heavy writers.
         */
-       if (state > 0)
+       if (state > 0) {
                wait_for_some_buffers(dev);
+               wakeup_bdflush();
+       }
 }
 
 static __inline__ void __mark_dirty(struct buffer_head *bh)
index 98667af288760fed12ee935a1c4dc5ba20990760..60e43d5519b0432c5491f933105b3ba0b3590b87 100644 (file)
@@ -125,10 +125,6 @@ extern int total_inactive_shortage(void);
 extern void wakeup_kswapd(void);
 extern int try_to_free_pages(unsigned int gfp_mask);
 
-extern unsigned int zone_free_shortage(zone_t *zone);
-extern unsigned int zone_inactive_shortage(zone_t *zone);
-extern unsigned int zone_inactive_plenty(zone_t *zone);
-
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *);
 extern void rw_swap_page_nolock(int, swp_entry_t, char *);
index 5507bd465a9a1e95cec6ef4739632b60d333b279..be46786f660effaf7773761eb9bbb27768319957 100644 (file)
@@ -585,25 +585,23 @@ unsigned int nr_inactive_clean_pages (void)
  */
 unsigned int nr_free_buffer_pages (void)
 {
-       unsigned int sum;
-
-       sum = nr_free_pages();
-       sum += nr_inactive_clean_pages();
-       sum += nr_inactive_dirty_pages;
-
-       /*
-        * Keep our write behind queue filled, even if
-        * kswapd lags a bit right now.
-        */
-       if (sum < freepages.high + inactive_target)
-               sum = freepages.high + inactive_target;
-       /*
-        * We don't want dirty page writebehind to put too
-        * much pressure on the working set, but we want it
-        * to be possible to have some dirty pages in the
-        * working set without upsetting the writebehind logic.
-        */
-       sum += nr_active_pages >> 4;
+       unsigned int sum = 0;
+       zonelist_t *zonelist;
+       zone_t **zonep, *zone;
+
+       zonelist = contig_page_data.node_zonelists + (GFP_KERNEL & GFP_ZONEMASK);
+       zonep = zonelist->zones;
+
+       for (zone = *zonep++; zone; zone = *zonep++) {
+               unsigned int pages = zone->free_pages +
+                       zone->inactive_clean_pages +
+                       zone->inactive_dirty_pages;
+
+               /* Allow the buffer cache to fill up at least "pages_high" pages */
+               if (pages < zone->pages_high)
+                       pages = zone->pages_high;
+               sum += pages;
+       }
 
        return sum;
 }
@@ -622,53 +620,6 @@ unsigned int nr_free_highpages (void)
 }
 #endif
 
-unsigned int zone_free_shortage(zone_t *zone)
-{
-       int sum = 0;
-
-       if (!zone->size)
-               goto ret;
-
-       if (zone->inactive_clean_pages + zone->free_pages
-                       < zone->pages_high) {
-               sum += zone->pages_high;
-               sum -= zone->free_pages;
-               sum -= zone->inactive_clean_pages;
-       }
-ret:
-       return sum;
-}
-
-unsigned int zone_inactive_plenty(zone_t *zone)
-{
-       int inactive;
-
-       if (!zone->size)
-               return 0;
-               
-       inactive = zone->inactive_dirty_pages;
-       inactive += zone->inactive_clean_pages;
-       inactive += zone->free_pages;
-
-       return (inactive > (zone->size / 3));
-
-}
-unsigned int zone_inactive_shortage(zone_t *zone) 
-{
-       int sum = 0;
-
-       if (!zone->size)
-               goto ret;
-
-       sum = zone->pages_high;
-       sum -= zone->inactive_dirty_pages;
-       sum -= zone->inactive_clean_pages;
-       sum -= zone->free_pages;
-
-ret:
-     return (sum > 0 ? sum : 0);
-}
-
 /*
  * Show free area list (used inside shift_scroll-lock stuff)
  * We also calculate the percentage fragmentation. We do this by counting the
index 6bb196e1dc022b906952a7df6721fa4f4acc0866..23c6c4f964f8cb71fa26716c2c3e4c96a688d401 100644 (file)
  * doesn't count as having freed a page.
  */
 
+/*
+ * Estimate whether a zone has enough inactive or free pages..
+ */
+static unsigned int zone_inactive_plenty(zone_t *zone)
+{
+       unsigned int inactive;
+
+       if (!zone->size)
+               return 0;
+               
+       inactive = zone->inactive_dirty_pages;
+       inactive += zone->inactive_clean_pages;
+       inactive += zone->free_pages;
+
+       return (inactive > (zone->size / 3));
+}
+
+static unsigned int zone_inactive_shortage(zone_t *zone) 
+{
+       unsigned int inactive;
+
+       if (!zone->size)
+               return 0;
+
+       inactive = zone->inactive_dirty_pages;
+       inactive += zone->inactive_clean_pages;
+       inactive += zone->free_pages;
+
+       return inactive < zone->pages_high;
+}
+
+static unsigned int zone_free_plenty(zone_t *zone)
+{
+       unsigned int free;
+
+       free = zone->free_pages;
+       free += zone->inactive_clean_pages;
+
+       return free > zone->pages_high*2;
+}
+
+static unsigned int zone_free_shortage(zone_t *zone)
+{
+       unsigned int free;
+
+       free = zone->free_pages;
+       free += zone->inactive_clean_pages;
+
+       return zone->size && free < zone->pages_low;
+}
+
+
 /* mm->page_table_lock is held. mmap_sem is not held */
 static void try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page)
 {
@@ -434,7 +486,7 @@ out:
 #define MAX_LAUNDER            (4 * (1 << page_cluster))
 #define CAN_DO_FS              (gfp_mask & __GFP_FS)
 #define CAN_DO_IO              (gfp_mask & __GFP_IO)
-int do_page_launder(zone_t *zone, int gfp_mask, int sync)
+int page_launder(int gfp_mask, int sync)
 {
        int launder_loop, maxscan, cleaned_pages, maxlaunder;
        struct list_head * page_lru;
@@ -470,11 +522,10 @@ dirty_page_rescan:
                }
 
                /* 
-                * If we are doing zone-specific laundering, 
-                * avoid touching pages from zones which do 
-                * not have a free shortage.
+                * If this zone has plenty of pages free,
+                * don't spend time on cleaning it.
                 */
-               if (zone && !zone_free_shortage(page->zone)) {
+               if (zone_free_plenty(page->zone)) {
                        list_del(page_lru);
                        list_add(page_lru, &inactive_dirty_list);
                        continue;
@@ -649,31 +700,6 @@ page_active:
        return cleaned_pages;
 }
 
-int page_launder(int gfp_mask, int sync)
-{
-       int type = 0, ret = 0;
-       pg_data_t *pgdat = pgdat_list;
-       /*
-        * First do a global scan if there is a 
-        * global shortage.
-        */
-       if (free_shortage())
-               ret += do_page_launder(NULL, gfp_mask, sync);
-
-       /*
-        * Then check if there is any specific zone 
-        * needs laundering.
-        */
-       for (type = 0; type < MAX_NR_ZONES; type++) {
-               zone_t *zone = pgdat->node_zones + type;
-               
-               if (zone_free_shortage(zone)) 
-                       ret += do_page_launder(zone, gfp_mask, sync);
-       } 
-
-       return ret;
-}
-
 static inline void age_page_up(struct page *page)
 {
        unsigned age = page->age + PAGE_AGE_ADV;
@@ -807,12 +833,8 @@ int total_free_shortage(void)
                int i;
                for(i = 0; i < MAX_NR_ZONES; i++) {
                        zone_t *zone = pgdat->node_zones+ i;
-                       if (zone->size && (zone->inactive_clean_pages +
-                                       zone->free_pages < zone->pages_min)) {
-                               sum += zone->pages_min;
-                               sum -= zone->free_pages;
-                               sum -= zone->inactive_clean_pages;
-                       }
+
+                       sum += zone_free_shortage(zone);
                }
                pgdat = pgdat->node_next;
        } while (pgdat);