Merge mga-1-0-0-branch into trunk.
authorGareth Hughes <gareth@users.sourceforge.net>
Thu, 15 Feb 2001 08:12:14 +0000 (08:12 +0000)
committerGareth Hughes <gareth@users.sourceforge.net>
Thu, 15 Feb 2001 08:12:14 +0000 (08:12 +0000)
91 files changed:
libdrm/xf86drm.c
linux-core/Makefile.kernel
linux-core/drmP.h
linux-core/drm_agpsupport.c [moved from linux/agpsupport.c with 75% similarity]
linux-core/drm_auth.c [moved from linux/auth.c with 74% similarity]
linux-core/drm_bufs.c [new file with mode: 0644]
linux-core/drm_context.c [new file with mode: 0644]
linux-core/drm_dma.c [moved from linux/dma.c with 76% similarity]
linux-core/drm_drawable.c [moved from linux/drawable.c with 75% similarity]
linux-core/drm_drv.c [new file with mode: 0644]
linux-core/drm_fops.c [moved from linux/fops.c with 89% similarity]
linux-core/drm_init.c [moved from linux/init.c with 83% similarity]
linux-core/drm_ioctl.c [new file with mode: 0644]
linux-core/drm_lock.c [moved from linux/lock.c with 77% similarity]
linux-core/drm_memory.h [moved from linux/memory.c with 57% similarity]
linux-core/drm_proc.c [moved from linux/proc.c with 64% similarity]
linux-core/drm_stub.c [new file with mode: 0644]
linux-core/drm_vm.c [moved from linux/vm.c with 84% similarity]
linux-core/i810_dma.c
linux-core/i810_drv.c
linux-core/i810_drv.h
linux-core/mga_drv.c
linux-core/r128_drv.c
linux-core/radeon_drv.c
linux-core/tdfx_drv.c
linux/Makefile.kernel
linux/Makefile.linux
linux/bufs.c [deleted file]
linux/ctxbitmap.c [deleted file]
linux/drm.h
linux/drmP.h
linux/drm_agpsupport.h [new file with mode: 0644]
linux/drm_auth.h [new file with mode: 0644]
linux/drm_bufs.h [new file with mode: 0644]
linux/drm_context.h [new file with mode: 0644]
linux/drm_dma.h [new file with mode: 0644]
linux/drm_drawable.h [new file with mode: 0644]
linux/drm_drv.h [new file with mode: 0644]
linux/drm_fops.h [new file with mode: 0644]
linux/drm_init.h [new file with mode: 0644]
linux/drm_ioctl.h [new file with mode: 0644]
linux/drm_lists.h [moved from linux/lists.c with 78% similarity]
linux/drm_lock.h [new file with mode: 0644]
linux/drm_memory.h [new file with mode: 0644]
linux/drm_proc.h [new file with mode: 0644]
linux/drm_stub.h [new file with mode: 0644]
linux/drm_vm.h [new file with mode: 0644]
linux/gamma.h [new file with mode: 0644]
linux/gamma_context.c [moved from linux/context.c with 91% similarity]
linux/gamma_dma.c
linux/gamma_drm.c [new file with mode: 0644]
linux/gamma_drv.c
linux/gamma_drv.h
linux/i810.h [new file with mode: 0644]
linux/i810_bufs.c [deleted file]
linux/i810_context.c [deleted file]
linux/i810_dma.c
linux/i810_drv.c
linux/i810_drv.h
linux/ioctl.c [deleted file]
linux/mga.h [new file with mode: 0644]
linux/mga_bufs.c [deleted file]
linux/mga_context.c [deleted file]
linux/mga_dma.c
linux/mga_drm.h
linux/mga_drv.c
linux/mga_drv.h
linux/mga_state.c
linux/mga_ucode.h [new file with mode: 0644]
linux/mga_warp.c [new file with mode: 0644]
linux/r128.h [new file with mode: 0644]
linux/r128_cce.c
linux/r128_context.c [deleted file]
linux/r128_drm.h
linux/r128_drv.c
linux/r128_drv.h
linux/r128_state.c
linux/radeon.h [new file with mode: 0644]
linux/radeon_bufs.c [deleted file]
linux/radeon_context.c [deleted file]
linux/radeon_cp.c
linux/radeon_drv.c
linux/radeon_drv.h
linux/radeon_state.c
linux/tdfx.h [new file with mode: 0644]
linux/tdfx_context.c [deleted file]
linux/tdfx_drv.c
linux/tdfx_drv.h [deleted file]
shared-core/drm.h
shared/drm.h
tests/dristat.c [new file with mode: 0644]

index 5c2c08c..e472aad 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>
  *         Kevin E. Martin <martin@valinux.com>
  *
  * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.17 2000/09/24 13:51:32 alanh Exp $
- * 
+ *
  */
 
 #ifdef XFree86Server
@@ -119,7 +119,7 @@ void drmFree(void *pt)
 static char *drmStrdup(const char *s)
 {
     char *retval = NULL;
-    
+
     if (s) {
        retval = _DRM_MALLOC(strlen(s)+1);
        strcpy(retval, s);
@@ -213,7 +213,7 @@ int drmAvailable(void)
     drmVersionPtr version;
     int           retval = 0;
     int           fd;
-    
+
     if (!access("/proc/dri/0", R_OK)) return 1;
 
     sprintf(dev_name, "/dev/dri-temp-%d", getpid());
@@ -408,7 +408,7 @@ drmVersionPtr drmGetVersion(int fd)
     version->date        = NULL;
     version->desc_len    = 0;
     version->desc        = NULL;
-    
+
     if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
        drmFreeKernelVersion(version);
        return NULL;
@@ -421,7 +421,7 @@ drmVersionPtr drmGetVersion(int fd)
        version->date    = drmMalloc(version->date_len + 1);
     if (version->desc_len)
        version->desc    = drmMalloc(version->desc_len + 1);
-    
+
     if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
        drmFreeKernelVersion(version);
        return NULL;
@@ -503,7 +503,7 @@ int drmAddMap(int fd,
     map.offset  = offset;
 #ifdef __alpha__
     /* Make sure we add the bus_base to all but shm */
-    if (type != DRM_SHM) 
+    if (type != DRM_SHM)
        map.offset += BUS_BASE;
 #endif
     map.size    = size;
@@ -519,14 +519,14 @@ int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
               int agp_offset)
 {
     drm_buf_desc_t request;
-    
+
     request.count     = count;
     request.size      = size;
     request.low_mark  = 0;
     request.high_mark = 0;
     request.flags     = flags;
     request.agp_start = agp_offset;
-   
+
     if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
     return request.count;
 }
@@ -542,16 +542,16 @@ int drmMarkBufs(int fd, double low, double high)
     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
 
     if (!info.count) return -EINVAL;
-    
+
     if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
        return -ENOMEM;
-       
+
     if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
        int retval = -errno;
        drmFree(info.list);
        return retval;
     }
-    
+
     for (i = 0; i < info.count; i++) {
        info.list[i].low_mark  = low  * info.list[i].count;
        info.list[i].high_mark = high * info.list[i].count;
@@ -562,7 +562,7 @@ int drmMarkBufs(int fd, double low, double high)
        }
     }
     drmFree(info.list);
-    
+
     return 0;
 }
 
@@ -630,7 +630,7 @@ drmBufInfoPtr drmGetBufInfo(int fd)
     if (info.count) {
        if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
            return NULL;
-       
+
        if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
            drmFree(info.list);
            return NULL;
@@ -657,7 +657,7 @@ drmBufMapPtr drmMapBufs(int fd)
     drm_buf_map_t bufs;
     drmBufMapPtr  retval;
     int           i;
-    
+
     bufs.count = 0;
     bufs.list  = NULL;
     if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
@@ -689,16 +689,19 @@ drmBufMapPtr drmMapBufs(int fd)
 int drmUnmapBufs(drmBufMapPtr bufs)
 {
     int i;
-    
+
     for (i = 0; i < bufs->count; i++) {
        munmap(bufs->list[i].address, bufs->list[i].total);
     }
     return 0;
 }
 
+#define DRM_DMA_RETRY          16
+
 int drmDMA(int fd, drmDMAReqPtr request)
 {
     drm_dma_t dma;
+    int ret, i = 0;
 
                                /* Copy to hidden structure */
     dma.context         = request->context;
@@ -710,10 +713,17 @@ int drmDMA(int fd, drmDMAReqPtr request)
     dma.request_size    = request->request_size;
     dma.request_indices = request->request_list;
     dma.request_sizes   = request->request_sizes;
-    if (ioctl(fd, DRM_IOCTL_DMA, &dma)) return -errno;
-    request->granted_count = dma.granted_count;
-    
-    return 0;
+
+    do {
+       ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
+    } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
+
+    if ( ret == 0 ) {
+       request->granted_count = dma.granted_count;
+       return 0;
+    } else {
+       return -errno;
+    }
 }
 
 int drmGetLock(int fd, drmContext context, drmLockFlags flags)
@@ -728,7 +738,7 @@ int drmGetLock(int fd, drmContext context, drmLockFlags flags)
     if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
     if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
     if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
-    
+
     while (ioctl(fd, DRM_IOCTL_LOCK, &lock))
        ;
     return 0;
@@ -827,7 +837,7 @@ int drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags)
     if (ctx.flags & _DRM_CONTEXT_2DONLY)    *flags |= DRM_CONTEXT_2DONLY;
     return 0;
 }
-    
+
 int drmDestroyContext(int fd, drmContext handle)
 {
     drm_ctx_t ctx;
@@ -1074,7 +1084,7 @@ void *drmGetContextTag(int fd, drmContext context)
 {
     drmHashEntry  *entry = drmGetEntry(fd);
     void          *value;
-    
+
     if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
 
     return value;
@@ -1108,7 +1118,7 @@ static void drmSIGIOHandler(int interrupt, void *closure)
 #if 0
                fprintf(stderr, "Got %s\n", buf);
 #endif
-               
+
                for (pt = buf; *pt != ' '; ++pt); /* Find first space */
                ++pt;
                old    = strtol(pt, &pt, 0);
@@ -1141,7 +1151,7 @@ int drmRemoveSIGIOHandler(int fd)
     drmHashEntry     *entry = drmGetEntry(fd);
 
     entry->f = NULL;
-    
+
     return xf86RemoveSIGIOHandler(fd);
 }
 #endif
index 9fe0038..a39b3cc 100644 (file)
@@ -62,7 +62,7 @@ obj-$(CONFIG_DRM_MGA)    += mga.o
 obj-$(CONFIG_DRM_I810)   += i810.o
 
 
-# When linking into the kernel, link the library just once. 
+# 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))
@@ -75,7 +75,7 @@ endif
 
 include $(TOPDIR)/Rules.make
 
-$(patsubst %.o,%.c,$(lib-objs-mod)): 
+$(patsubst %.o,%.c,$(lib-objs-mod)):
        @ln -sf $(subst -mod,,$@) $@
 
 drmlib-mod.a: $(lib-objs-mod)
index 9a8fe61..58d98f5 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>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #ifndef _DRM_P_H_
 #endif
 #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_DMA
+#define __HAVE_DMA             0
+#endif
+#ifndef __HAVE_DMA_WAITLIST
+#define __HAVE_DMA_WAITLIST    0
+#endif
+#ifndef __HAVE_DMA_FREELIST
+#define __HAVE_DMA_FREELIST    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_MEM_TOTALAGP  16
 #define DRM_MEM_BOUNDAGP  17
 #define DRM_MEM_CTXBITMAP 18
+#define DRM_MEM_STUB      19
 
 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 
@@ -259,16 +286,16 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
        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)
@@ -276,22 +303,22 @@ 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; return len; }
+#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 )
+       (map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
 
 #define DRM_IOREMAPFREE(map)                                           \
        do {                                                            \
                if ( (map)->handle && (map)->size )                     \
-                       drm_ioremapfree( (map)->handle, (map)->size );  \
+                       DRM(ioremapfree)( (map)->handle, (map)->size ); \
        } while (0)
 
 #define DRM_FIND_MAP(map, o)                                           \
@@ -314,8 +341,8 @@ 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);
+typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg );
 
 typedef struct drm_ioctl_desc {
        drm_ioctl_t          *func;
@@ -463,9 +490,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    */
@@ -479,6 +508,7 @@ 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               */
@@ -492,6 +522,7 @@ 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;
@@ -501,7 +532,7 @@ typedef struct drm_device_dma {
        unsigned long     *pagelist;
        unsigned long     byte_count;
        enum {
-          _DRM_DMA_USE_AGP = 0x01
+               _DRM_DMA_USE_AGP = 0x01
        } flags;
 
                                /* DMA support */
@@ -511,7 +542,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;
@@ -559,17 +590,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;
@@ -617,7 +641,7 @@ typedef struct drm_device {
        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
        unsigned long     *ctx_bitmap;
@@ -630,227 +654,262 @@ typedef struct drm_device {
                                /* Internal function definitions */
 
                                /* Misc. support (init.c) */
-extern int          drm_flags;
-extern void         drm_parse_options(char *s);
-extern int           drm_cpu_valid(void);
+extern int          DRM(flags);
+extern void         DRM(parse_options)( char *s );
+extern int           DRM(cpu_valid)( void );
 
+                               /* 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);
 
                                /* 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);
+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 (vm.c) */
 #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_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,
+                                       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,
+extern struct page *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,
-                                     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);
+#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);
+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);
 
                                /* 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(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,
-                                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);
-#endif
-
-
                                /* 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,
+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);
 
-
                                /* 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,
-                                  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(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);
 
                                /* Drawable IOCTL support (drawable.c) */
-extern int          drm_adddraw(struct inode *inode, struct file *filp,
+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);
-extern int          drm_rmdraw(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,
-                                 unsigned int cmd, unsigned long arg);
-extern int          drm_authmagic(struct inode *inode, struct file *filp,
+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(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,
-                                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,
+extern int          DRM(block)(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);
+extern int          DRM(unblock)(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(ctxbitmap_init)( drm_device_t *dev );
+extern void         DRM(ctxbitmap_cleanup)( drm_device_t *dev );
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+
+
+
+                               /* 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,
+                                  unsigned int cmd, unsigned long arg );
+
+
+#if __HAVE_DMA
+                               /* DMA support (dma.c) */
+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);
+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);
+#if 0
+extern int          DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
+#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
+#endif
+
+                               /* Buffer list management support (lists.c) */
+#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
+
+#if __REALLY_HAVE_AGP
                                /* 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,
+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);
+
+                               /* 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);
+
 #endif
 #endif
 #endif
similarity index 75%
rename from linux/agpsupport.c
rename to linux-core/drm_agpsupport.c
index c996df8..b070a59 100644 (file)
@@ -1,4 +1,4 @@
-/* agpsupport.c -- DRM support for AGP/GART backend -*- linux-c -*-
+/* 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.
  * 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.
- * 
- * Author: 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.
  *
+ * 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
@@ -40,8 +44,8 @@
 
 static const drm_agp_t *drm_agp = NULL;
 
-int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
+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;
@@ -66,8 +70,8 @@ int drm_agp_info(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
+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;
@@ -79,8 +83,8 @@ int drm_agp_acquire(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
+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;
@@ -89,16 +93,16 @@ int drm_agp_release(struct inode *inode, struct file *filp, unsigned int cmd,
        drm_agp->release();
        dev->agp->acquired = 0;
        return 0;
-       
+
 }
 
-void _drm_agp_release(void)
+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)
+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;
@@ -108,7 +112,7 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd,
 
        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;
@@ -116,8 +120,8 @@ int drm_agp_enable(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
-                 unsigned long arg)
+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;
@@ -126,22 +130,23 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
        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)))
+       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);
+       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;
@@ -157,15 +162,15 @@ int drm_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
        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);
+               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)
+static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
+                                           unsigned long handle)
 {
        drm_agp_mem_t *entry;
 
@@ -175,8 +180,8 @@ static drm_agp_mem_t *drm_agp_lookup_entry(drm_device_t *dev,
        return NULL;
 }
 
-int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd,
-                  unsigned long arg)
+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;
@@ -186,14 +191,14 @@ int drm_agp_unbind(struct inode *inode, struct file *filp, unsigned int cmd,
        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)))
+       if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
                return -EINVAL;
        if (!entry->bound) return -EINVAL;
-       return drm_unbind_agp(entry->memory);
+       return DRM(unbind_agp)(entry->memory);
 }
 
-int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd,
-                unsigned long arg)
+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;
@@ -201,56 +206,56 @@ int drm_agp_bind(struct inode *inode, struct file *filp, unsigned int cmd,
        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)))
+       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;
+       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", 
+       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)
+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)))
+       if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
                return -EINVAL;
-       if (entry->bound) drm_unbind_agp(entry->memory);
-   
+       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);
+       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 *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)))
+               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);
+                       DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
                        return NULL;
                }
                head->memory = NULL;
@@ -271,9 +276,9 @@ drm_agp_head_t *drm_agp_init(void)
 
 #if LINUX_VERSION_CODE >= 0x020400
                case VIA_MVP4:          head->chipset = "VIA MVP4";      break;
-               case VIA_APOLLO_KX133:  head->chipset = "VIA Apollo KX133"; 
+               case VIA_APOLLO_KX133:  head->chipset = "VIA Apollo KX133";
                        break;
-               case VIA_APOLLO_KT133:  head->chipset = "VIA Apollo KT133"; 
+               case VIA_APOLLO_KT133:  head->chipset = "VIA Apollo KT133";
                        break;
 #endif
 
@@ -296,33 +301,35 @@ drm_agp_head_t *drm_agp_init(void)
        return head;
 }
 
-void drm_agp_uninit(void)
+void DRM(agp_uninit)(void)
 {
        DRM_AGP_PUT;
        drm_agp = NULL;
 }
 
-agp_memory *drm_agp_allocate_memory(size_t pages, u32 type)
+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)
+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)
+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)
+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 */
similarity index 74%
rename from linux/auth.c
rename to linux-core/drm_auth.c
index 80bb4b6..2636e61 100644 (file)
@@ -1,5 +1,5 @@
-/* auth.c -- IOCTLs for authentication -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #define __NO_VERSION__
 #include "drmP.h"
 
-static int drm_hash_magic(drm_magic_t magic)
+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)
+static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
 {
        drm_file_t        *retval = NULL;
        drm_magic_entry_t *pt;
-       int               hash    = drm_hash_magic(magic);
+       int               hash    = DRM(hash_magic)(magic);
 
        down(&dev->struct_sem);
        for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
@@ -54,15 +54,15 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
        return retval;
 }
 
-int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+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);
+
+       hash         = DRM(hash_magic)(magic);
+       entry        = DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
        if (!entry) return -ENOMEM;
        entry->magic = magic;
        entry->priv  = priv;
@@ -77,19 +77,19 @@ int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
                dev->magiclist[hash].tail       = entry;
        }
        up(&dev->struct_sem);
-       
+
        return 0;
 }
 
-int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+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);
-       
+       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) {
@@ -108,13 +108,13 @@ int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
        }
        up(&dev->struct_sem);
 
-       drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
-       
+       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)
+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;
@@ -131,19 +131,19 @@ int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
                        if (!sequence) ++sequence; /* reserve 0 */
                        auth.magic = sequence++;
                        spin_unlock(&lock);
-               } while (drm_find_file(dev, auth.magic));
+               } while (DRM(find_file)(dev, auth.magic));
                priv->magic = auth.magic;
-               drm_add_magic(dev, priv, 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)
+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;
@@ -153,9 +153,9 @@ int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd,
        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))) {
+       if ((file = DRM(find_file)(dev, auth.magic))) {
                file->authenticated = 1;
-               drm_remove_magic(dev, auth.magic);
+               DRM(remove_magic)(dev, auth.magic);
                return 0;
        }
        return -EINVAL;
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
new file mode 100644 (file)
index 0000000..f2613a9
--- /dev/null
@@ -0,0 +1,757 @@
+/* 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 "drmP.h"
+
+#ifndef __HAVE_PCI_DMA
+#define __HAVE_PCI_DMA         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;
+
+       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 __REALLY_HAVE_AGP
+       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;
+}
+
+#if __HAVE_DMA
+
+#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;
+
+       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 */
+       }
+
+       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 );
+               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
+               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 );
+
+       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 = 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 );
+
+/* GH: Please leave this disabled for now.  I need to fix this properly...
+ */
+#if 0
+       /* FIXME: work this mess out...
+        */
+       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;
+
+       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 */
+       }
+
+       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 ) {
+               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 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 = 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);
+
+/* GH: Please leave this disabled for now.  I need to fix this properly...
+ */
+#if 0
+       /* FIXME: work this mess out...
+        */
+       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 */
+
+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_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) ) {
+                       drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
+
+                       if ( !map ) {
+                               retcode = -EINVAL;
+                               goto done;
+                       }
+
+                       down( &current->mm->mmap_sem );
+                       virtual = do_mmap( filp, 0, map->size,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED,
+                                          (unsigned long)map->offset );
+                       up( &current->mm->mmap_sem );
+               } else {
+                       down( &current->mm->mmap_sem );
+                       virtual = do_mmap( filp, 0, dma->byte_count,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED, 0 );
+                       up( &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;
+}
+
+#endif /* __HAVE_DMA */
diff --git a/linux-core/drm_context.c b/linux-core/drm_context.c
new file mode 100644 (file)
index 0000000..6bbcfca
--- /dev/null
@@ -0,0 +1,270 @@
+/* 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>
+ */
+
+/* ================================================================
+ * Context bitmap support
+ */
+
+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 );
+}
+
+
+/* ================================================================
+ * 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 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 ) {
+                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 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 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;
+}
similarity index 76%
rename from linux/dma.c
rename to linux-core/drm_dma.c
index 56dd244..35eb896 100644 (file)
@@ -1,5 +1,5 @@
-/* dma.c -- DMA IOCTL and function support -*- linux-c -*-
- * Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
+/* 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.
  * 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.
- * 
- * Authors:
- *    Rickard E. (Rik) Faith <faith@valinuxa.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>
  */
 
 #define __NO_VERSION__
 
 #include <linux/interrupt.h>   /* For task queue support */
 
-void drm_dma_setup(drm_device_t *dev)
+#ifndef __HAVE_DMA_WAITQUEUE
+#define __HAVE_DMA_WAITQUEUE   0
+#endif
+#ifndef __HAVE_DMA_RECLAIM
+#define __HAVE_DMA_RECLAIM     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);
-       memset(dev->dma, 0, sizeof(*dev->dma));
-       for (i = 0; i <= DRM_MAX_ORDER; 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)
+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) {
@@ -60,49 +75,52 @@ void drm_dma_takedown(drm_device_t *dev)
                                  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_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);
+                       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[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);
+                       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);
+               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)(dma->pagelist,
+                         dma->page_count * sizeof(*dma->pagelist),
+                         DRM_MEM_PAGES);
        }
-       drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
+       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 DRM(histogram_slot)(unsigned long count)
 {
        int value = DRM_DMA_HISTOGRAM_INITIAL;
        int slot;
@@ -115,13 +133,13 @@ int drm_histogram_slot(unsigned long count)
        return DRM_DMA_HISTOGRAM_SLOTS - 1;
 }
 
-void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
+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);
@@ -130,21 +148,21 @@ void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
                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);
+               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);
 
-               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]);
 
@@ -156,12 +174,10 @@ void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
 }
 #endif
 
-void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+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;
@@ -169,18 +185,24 @@ void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
 #if DRM_DMA_HISTOGRAM
        buf->time_completed = get_cycles();
 #endif
-       if (waitqueue_active(&buf->dma_wait)) {
+
+       if ( __HAVE_DMA_WAITQUEUE && waitqueue_active(&buf->dma_wait)) {
                wake_up_interruptible(&buf->dma_wait);
-       } else {
+       }
+#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);
+               DRM(freelist_put)(dev, &dma->bufs[buf->order].freelist, buf);
        }
+#endif
 }
 
-void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
+#if !__HAVE_DMA_RECLAIM
+void DRM(reclaim_buffers)(drm_device_t *dev, pid_t pid)
 {
        drm_device_dma_t *dma = dev->dma;
        int              i;
@@ -190,7 +212,7 @@ void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
                if (dma->buflist[i]->pid == pid) {
                        switch (dma->buflist[i]->list) {
                        case DRM_LIST_NONE:
-                               drm_free_buffer(dev, dma->buflist[i]);
+                               DRM(free_buffer)(dev, dma->buflist[i]);
                                break;
                        case DRM_LIST_WAIT:
                                dma->buflist[i]->list = DRM_LIST_RECLAIM;
@@ -202,13 +224,21 @@ void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
                }
        }
 }
+#endif
+
+
+/* GH: This is a big hack for now...
+ */
+#if __HAVE_OLD_DMA
 
 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");
@@ -218,7 +248,7 @@ int drm_context_switch(drm_device_t *dev, int old, int new)
 #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) {
@@ -230,7 +260,7 @@ int drm_context_switch(drm_device_t *dev, int old, int new)
                clear_bit(0, &dev->context_flag);
                return 0;
        }
-       
+
        q = dev->queuelist[new];
        atomic_inc(&q->use_count);
        if (atomic_read(&q->use_count) == 1) {
@@ -239,51 +269,51 @@ int drm_context_switch(drm_device_t *dev, int old, int new)
                return -EINVAL;
        }
 
-       if (drm_flags & DRM_FLAG_NOCTX) {
+       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);
+               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,
+               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()
+       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)
+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);
@@ -291,8 +321,7 @@ void drm_clear_next_buffer(drm_device_t *dev)
        dma->next_queue  = NULL;
 }
 
-
-int drm_select_queue(drm_device_t *dev, void (*wrapper)(unsigned long))
+int DRM(select_queue)(drm_device_t *dev, void (*wrapper)(unsigned long))
 {
        int        i;
        int        candidate = -1;
@@ -360,7 +389,7 @@ int drm_select_queue(drm_device_t *dev, void (*wrapper)(unsigned long))
 }
 
 
-int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
+int DRM(dma_enqueue)(drm_device_t *dev, drm_dma_t *d)
 {
        int               i;
        drm_queue_t       *q;
@@ -374,7 +403,7 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
 
        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");
@@ -413,7 +442,7 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
                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) {
@@ -457,27 +486,27 @@ int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *d)
                buf->waiting = 1;
                if (atomic_read(&q->use_count) == 1
                    || atomic_read(&q->finalization)) {
-                       drm_free_buffer(dev, buf);
+                       DRM(free_buffer)(dev, buf);
                } else {
-                       drm_waitlist_put(&q->waitlist, buf);
+                       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)
+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);
+               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",
@@ -503,16 +532,16 @@ static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *d,
 }
 
 
-int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
+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);
+
+       order = DRM(order)(dma->request_size);
 
        dma->granted_count = 0;
-       retcode            = drm_dma_get_buffers_of_order(dev, dma, order);
+       retcode            = DRM(dma_get_buffers_of_order)(dev, dma, order);
 
        if (dma->granted_count < dma->request_count
            && (dma->flags & _DRM_DMA_SMALLER_OK)) {
@@ -521,9 +550,9 @@ int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
                             && dma->granted_count < dma->request_count
                             && tmp_order >= DRM_MIN_ORDER;
                     --tmp_order) {
-                       
-                       retcode = drm_dma_get_buffers_of_order(dev, dma,
-                                                              tmp_order);
+
+                       retcode = DRM(dma_get_buffers_of_order)(dev, dma,
+                                                               tmp_order);
                }
        }
 
@@ -534,10 +563,14 @@ int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
                             && dma->granted_count < dma->request_count
                             && tmp_order <= DRM_MAX_ORDER;
                     ++tmp_order) {
-                       
-                       retcode = drm_dma_get_buffers_of_order(dev, dma,
-                                                              tmp_order);
+
+                       retcode = DRM(dma_get_buffers_of_order)(dev, dma,
+                                                               tmp_order);
                }
        }
        return 0;
 }
+
+#endif
+
+#endif
similarity index 75%
rename from linux/drawable.c
rename to linux-core/drm_drawable.c
index 1328054..13e46b9 100644 (file)
@@ -1,5 +1,5 @@
-/* drawable.c -- IOCTLs for drawables -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #define __NO_VERSION__
 #include "drmP.h"
 
-int drm_adddraw(struct inode *inode, struct file *filp, unsigned int cmd,
-               unsigned long arg)
+int DRM(adddraw)(struct inode *inode, struct file *filp,
+                unsigned int cmd, unsigned long arg)
 {
        drm_draw_t draw;
 
@@ -44,8 +44,8 @@ int drm_adddraw(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_rmdraw(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+int DRM(rmdraw)(struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
 {
        return 0;               /* NOOP */
 }
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
new file mode 100644 (file)
index 0000000..b24d213
--- /dev/null
@@ -0,0 +1,927 @@
+/* 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 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_IOCTLS
+#define DRIVER_IOCTLS
+#endif
+
+
+static drm_device_t    DRM(device);
+static int              DRM(minor);
+
+static struct file_operations  DRM(fops) = {
+#if LINUX_VERSION_CODE >= 0x020400
+                               /* This started being used during 2.4.0-test */
+       owner:   THIS_MODULE,
+#endif
+       open:    DRM(open),
+       flush:   DRM(flush),
+       release: DRM(release),
+       ioctl:   DRM(ioctl),
+       mmap:    DRM(mmap),
+       read:    DRM(read),
+       fasync:  DRM(fasync),
+       poll:    DRM(poll),
+};
+
+
+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_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
+
+       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" );
+
+#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.
+ */
+
+static int __init DRM(options)( char *str )
+{
+       DRM(parse_options)( str );
+       return 1;
+}
+
+__setup( DRIVER_NAME "=", DRM(options) );
+#endif
+
+static int DRM(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 );
+
+#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 = 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 DRM(takedown)( drm_device_t *dev )
+{
+       drm_magic_entry_t *pt, *next;
+       drm_map_t *map;
+       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;
+       }
+
+                               /* 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:
+#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:
+                               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 __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;
+}
+
+/* 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 = &DRM(device);
+#if __HAVE_CTX_BITMAP
+       int retcode;
+#endif
+       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)( drm_opts );
+#endif
+       DRIVER_PREINIT();
+
+       DRM(mem_init)();
+
+       if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
+               return -EPERM;
+       dev->device = MKDEV(DRM_MAJOR, DRM(minor) );
+       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));
+               DRM(takedown)( dev );
+               return -ENOMEM;
+       }
+#endif
+#if __REALLY_HAVE_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 __HAVE_CTX_BITMAP
+       retcode = DRM(ctxbitmap_init)( dev );
+       if( retcode ) {
+               DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+               DRM(stub_unregister)(DRM(minor));
+               DRM(takedown)( dev );
+               return retcode;
+       }
+#endif
+
+       DRIVER_POSTINIT();
+
+       DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
+                 DRIVER_NAME,
+                 DRIVER_MAJOR,
+                 DRIVER_MINOR,
+                 DRIVER_PATCHLEVEL,
+                 DRIVER_DATE,
+                 DRM(minor) );
+
+       return 0;
+}
+
+/* drm_cleanup is called via cleanup_module at module unload time.
+ */
+static void __exit drm_cleanup( void )
+{
+       drm_device_t *dev = &DRM(device);
+
+       DRM_DEBUG( "\n" );
+
+       if ( DRM(stub_unregister)(DRM(minor)) ) {
+               DRM_ERROR( "Cannot unload module\n" );
+       } else {
+               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 ) {
+               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
+}
+
+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 = &DRM(device);
+       int retcode = 0;
+
+       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_ERROR( "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 );
+               }
+       }
+#else
+       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 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 __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
+        }
+
+        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 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;
+}
similarity index 89%
rename from linux/fops.c
rename to linux-core/drm_fops.c
index 8e373e5..d646f31 100644 (file)
@@ -1,5 +1,5 @@
-/* fops.c -- File operations for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  *    Daryll Strauss <daryll@valinux.com>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #define __NO_VERSION__
 
 /* drm_open is called whenever a process opens /dev/drm. */
 
-int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
+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;
+       if (!DRM(cpu_valid)())        return -EINVAL;
 
        DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
 
-       priv                = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+       priv                = DRM(alloc)(sizeof(*priv), DRM_MEM_FILES);
        memset(priv, 0, sizeof(*priv));
        filp->private_data  = priv;
        priv->uid           = current->euid;
@@ -69,11 +69,11 @@ int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
                dev->file_last       = priv;
        }
        up(&dev->struct_sem);
-       
+
        return 0;
 }
 
-int drm_flush(struct file *filp)
+int DRM(flush)(struct file *filp)
 {
        drm_file_t    *priv   = filp->private_data;
        drm_device_t  *dev    = priv->dev;
@@ -83,6 +83,7 @@ int drm_flush(struct file *filp)
        return 0;
 }
 
+#if 0
 /* drm_release is called whenever a process closes /dev/drm*.  Linux calls
    this only if any mappings have been closed. */
 
@@ -103,7 +104,7 @@ int drm_release(struct inode *inode, struct file *filp)
                drm_lock_free(dev,
                              &dev->lock.hw_lock->lock,
                              _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-               
+
                                /* FIXME: may require heavy-handed reset of
                                    hardware at this point, possibly
                                    processed via a callback to the X
@@ -119,18 +120,19 @@ int drm_release(struct inode *inode, struct file *filp)
        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;
 }
+#endif
 
-int drm_fasync(int fd, struct file *filp, int on)
+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;
@@ -142,7 +144,7 @@ int drm_fasync(int fd, struct file *filp, int on)
    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)
+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;
@@ -152,7 +154,7 @@ ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off)
        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) {
@@ -182,12 +184,12 @@ ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off)
                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 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);
@@ -195,7 +197,7 @@ int drm_write_string(drm_device_t *dev, const char *s)
 
        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,
@@ -239,7 +241,7 @@ int drm_write_string(drm_device_t *dev, const char *s)
        return 0;
 }
 
-unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
+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;
similarity index 83%
rename from linux/init.c
rename to linux-core/drm_init.c
index 8de3dac..9ae9841 100644 (file)
@@ -1,5 +1,5 @@
-/* init.c -- Setup/Cleanup for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #define __NO_VERSION__
 #include "drmP.h"
 
-int                          drm_flags         = 0;
+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)
+ * 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(flags) |= DRM_FLAG_NOCTX;
                DRM_INFO("Server-mediated context switching OFF\n");
                return;
        }
        if (!strcmp(s, "debug")) {
-               drm_flags |= DRM_FLAG_DEBUG;
+               DRM(flags) |= DRM_FLAG_DEBUG;
                DRM_INFO("Debug messages ON\n");
                return;
        }
@@ -67,7 +67,7 @@ static void drm_parse_option(char *s)
  * drm         ::= 'drm=' option_list
  * option_list ::= option [ ';' option_list ]
  * option      ::= 'device:' major
- *             |   'debug' 
+ *             |   'debug'
  *             |   'noctx'
  * major       ::= INTEGER
  *
@@ -82,10 +82,10 @@ static void drm_parse_option(char *s)
  *
  */
 
-void drm_parse_options(char *s)
+void DRM(parse_options)(char *s)
 {
        char *h, *t, *n;
-       
+
        DRM_DEBUG("\"%s\"\n", s ?: "");
        if (!s || !*s) return;
 
@@ -93,21 +93,20 @@ void drm_parse_options(char *s)
                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(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)
+ * 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. */
+       return 0; /* No cmpxchg before v9 sparc. */
 #endif
        return 1;
 }
diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c
new file mode 100644 (file)
index 0000000..ce6ac2e
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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)
+               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;
+}
+
+
+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;
+       int          idx;
+
+       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;
+       }
+       map.offset = dev->maplist[idx]->offset;
+       map.size   = dev->maplist[idx]->size;
+       map.type   = dev->maplist[idx]->type;
+       map.flags  = dev->maplist[idx]->flags;
+       map.handle = dev->maplist[idx]->handle;
+       map.mtrr   = dev->maplist[idx]->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;
+}
similarity index 77%
rename from linux/lock.c
rename to linux-core/drm_lock.c
index 90d2f13..c10cfe2 100644 (file)
@@ -1,5 +1,5 @@
 /* lock.c -- IOCTLs for locking -*- linux-c -*-
- * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
+ * 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.
  * 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>
  */
 
 #define __NO_VERSION__
 #include "drmP.h"
 
-int drm_block(struct inode *inode, struct file *filp, unsigned int cmd,
-             unsigned long arg)
+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)
+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)
+int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
 {
        unsigned int old, new, prev;
 
@@ -74,8 +74,8 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
 
 /* 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)
+int DRM(lock_transfer)(drm_device_t *dev,
+                      __volatile__ unsigned int *lock, unsigned int context)
 {
        unsigned int old, new, prev;
 
@@ -88,8 +88,8 @@ int drm_lock_transfer(drm_device_t *dev,
        return 1;
 }
 
-int drm_lock_free(drm_device_t *dev,
-                 __volatile__ unsigned int *lock, unsigned int context)
+int DRM(lock_free)(drm_device_t *dev,
+                  __volatile__ unsigned int *lock, unsigned int context)
 {
        unsigned int old, new, prev;
        pid_t        pid = dev->lock.pid;
@@ -111,14 +111,14 @@ int drm_lock_free(drm_device_t *dev,
        return 0;
 }
 
-static int drm_flush_queue(drm_device_t *dev, int context)
+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);
@@ -138,19 +138,18 @@ static int drm_flush_queue(drm_device_t *dev, int context)
                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)
+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)) {
@@ -162,48 +161,48 @@ static int drm_flush_unblock_queue(drm_device_t *dev, int context)
        return 0;
 }
 
-int drm_flush_block_and_flush(drm_device_t *dev, int context,
-                             drm_lock_flags_t flags)
+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);
+               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);
+                       ret = DRM(flush_queue)(dev, i);
                }
        }
        return ret;
 }
 
-int drm_flush_unblock(drm_device_t *dev, int context, drm_lock_flags_t flags)
+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);
+               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);
+                       ret = DRM(flush_unblock_queue)(dev, i);
                }
        }
-               
+
        return ret;
 }
 
-int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
-              unsigned long arg)
+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;
@@ -214,24 +213,24 @@ int drm_finish(struct inode *inode, struct file *filp, unsigned int cmd,
 
        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);
+       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)
+int DRM(notifier)(void *priv)
 {
        drm_sigdata_t *s = (drm_sigdata_t *)priv;
        unsigned int  old, new, prev;
@@ -240,7 +239,7 @@ int drm_notifier(void *priv)
                                /* 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 {
similarity index 57%
rename from linux/memory.c
rename to linux-core/drm_memory.h
index 261fb34..caf0539 100644 (file)
@@ -1,5 +1,5 @@
-/* memory.c -- Memory management wrappers for DRM -*- linux-c -*-
- * Created: Thu Feb  4 14:00:34 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #define __NO_VERSION__
@@ -43,10 +43,10 @@ typedef struct drm_mem_stats {
        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[]   = {
+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"   },
@@ -66,53 +66,60 @@ static drm_mem_stats_t        drm_mem_stats[]   = {
        [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)
+void DRM(mem_init)(void)
 {
        drm_mem_stats_t *mem;
        struct sysinfo  si;
-       
-       for (mem = drm_mem_stats; mem->name; ++mem) {
+
+       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;
+       DRM(ram_available) = si.totalram >> PAGE_SHIFT;
 #else
-       drm_ram_available = si.totalram;
+       DRM(ram_available) = si.totalram;
 #endif
-       drm_ram_used      = 0;
+       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)
+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];
 
-       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(ram_available) << (PAGE_SHIFT - 10));
        DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
-                      "locked", 0, 0, 0, drm_ram_used >> 10);
+                      "locked", 0, 0, 0, DRM(ram_used) >> 10);
        DRM_PROC_PRINT("\n");
-       for (pt = drm_mem_stats; pt->name; pt++) {
+       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,
@@ -124,125 +131,127 @@ static int _drm_mem_info(char *buf, char **start, off_t offset, int len,
                               (long)pt->bytes_allocated
                               - (long)pt->bytes_freed);
        }
-       
-       return len;
+
+       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 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);
+
+       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 *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);
+               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);
+       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 *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
 {
        void *pt;
-       
-       if (!(pt = drm_alloc(size, area))) return NULL;
+
+       if (!(pt = DRM(alloc)(size, area))) return NULL;
        if (oldpt && oldsize) {
                memcpy(pt, oldpt, oldsize);
-               drm_free(oldpt, oldsize, area);
+               DRM(free)(oldpt, oldsize, area);
        }
        return pt;
 }
 
-char *drm_strdup(const char *s, int area)
+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;
+
+       if (!(pt = DRM(alloc)(length+1, area))) return NULL;
        strcpy(pt, s);
        return pt;
 }
 
-void drm_strfree(const char *s, int area)
+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);
+       DRM(free)((void *)s, size, area);
 }
 
-void drm_free(void *pt, size_t size, int 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);
+       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 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);
+
+       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);
-       
+       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);
+               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);
-       
-       
+       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;
@@ -254,18 +263,18 @@ unsigned long drm_alloc_pages(int order, int area)
                mem_map_reserve(MAP_NR(addr));
 #endif
        }
-       
+
        return address;
 }
 
-void drm_free_pages(unsigned long address, int order, int area)
+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 {
@@ -282,13 +291,13 @@ void drm_free_pages(unsigned long address, int order, int area)
                }
                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);
+
+       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",
@@ -296,45 +305,45 @@ void drm_free_pages(unsigned long address, int order, int area)
        }
 }
 
-void *drm_ioremap(unsigned long offset, unsigned long size)
+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);
+               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);
+       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)
+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);
+
+       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",
@@ -343,7 +352,9 @@ void drm_ioremapfree(void *pt, unsigned long size)
 }
 
 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-agp_memory *drm_alloc_agp(int pages, u32 type)
+#if __MUST_HAVE_AGP
+
+agp_memory *DRM(alloc_agp)(int pages, u32 type)
 {
        agp_memory *handle;
 
@@ -351,22 +362,22 @@ agp_memory *drm_alloc_agp(int pages, u32 type)
                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
+
+       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);
+               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);
+       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 DRM(free_agp)(agp_memory *handle, int pages)
 {
        int           alloc_count;
        int           free_count;
@@ -377,14 +388,14 @@ int drm_free_agp(agp_memory *handle, int pages)
                              "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
+
+       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);
+               spin_unlock(&DRM(mem_lock));
                if (free_count > alloc_count) {
                        DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
                                      "Excess frees: %d frees, %d allocs\n",
@@ -395,7 +406,7 @@ int drm_free_agp(agp_memory *handle, int pages)
        return retval;
 }
 
-int drm_bind_agp(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(agp_memory *handle, unsigned int start)
 {
        int retcode = -EINVAL;
 
@@ -405,39 +416,39 @@ int drm_bind_agp(agp_memory *handle, unsigned int start)
                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
+       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);
+               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);
+       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 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
+       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);
+       spin_unlock(&DRM(mem_lock));
        if (free_count > alloc_count) {
                DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
                              "Excess frees: %d frees, %d allocs\n",
@@ -446,3 +457,4 @@ int drm_unbind_agp(agp_memory *handle)
        return retcode;
 }
 #endif
+#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */
similarity index 64%
rename from linux/proc.c
rename to linux-core/drm_proc.c
index ca062a0..634673d 100644 (file)
@@ -1,5 +1,5 @@
-/* proc.c -- /proc support for DRM -*- linux-c -*-
- * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
+ *
+ * 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 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);
+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 len, int *eof, void *data);
+static int        DRM(vma_info)(char *buf, char **start, off_t offset,
+                                int request, 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);
+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    },
+} 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     },
+       { "vma",     DRM(vma_info)     },
 #endif
 #if DRM_DMA_HISTOGRAM
-       { "histo",   drm_histo_info   },
+       { "histo",   DRM(histo_info)   },
 #endif
 };
-#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0]))
+#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 *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];
 
-       drm_root = create_proc_entry("dri", S_IFDIR, NULL);
-       if (!drm_root) {
+       if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
+       if (!root) {
                DRM_ERROR("Cannot create /proc/dri\n");
-               return -1;
+               return NULL;
        }
 
-                               /* 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);
-               }
-               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;
+       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, drm_dev_root);
+               ent = create_proc_entry(DRM(proc_list)[i].name,
+                                       S_IFREG|S_IRUGO, *dev_root);
                if (!ent) {
-                       DRM_ERROR("Cannot create /proc/%s/%s\n",
-                                 drm_slot_name, drm_proc_list[i].name);
+                       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,
-                                                 drm_dev_root);
-                       remove_proc_entry(drm_slot_name, NULL);
-                       remove_proc_entry("dri", NULL);
-                       return -1;
+                               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->read_proc = DRM(proc_list)[i].f;
                ent->data      = dev;
        }
 
-       return 0;
+       return root;
 }
 
 
-int drm_proc_cleanup(void)
+int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
+                     struct proc_dir_entry *dev_root)
 {
-       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;
+       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 len,
-                        int *eof, void *data)
+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 > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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",
@@ -156,13 +153,17 @@ static int drm_name_info(char *buf, char **start, off_t offset, int len,
        } else {
                DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
        }
-       return len;
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int _drm_vm_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 request,
+                        int *eof, void *data)
 {
        drm_device_t *dev = (drm_device_t *)data;
+       int          len  = 0;
        drm_map_t    *map;
                                /* Hardcoded from _DRM_FRAME_BUFFER,
                                    _DRM_REGISTERS, _DRM_SHM, and
@@ -171,9 +172,14 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
        const char   *type;
        int          i;
 
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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");
        for (i = 0; i < dev->map_count; i++) {
@@ -194,32 +200,40 @@ static int _drm_vm_info(char *buf, char **start, off_t offset, int len,
                }
        }
 
-       return len;
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_vm_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 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, len, eof, data);
+       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 len,
-                           int *eof, void *data)
+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 > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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");
@@ -228,7 +242,7 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
                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",
+                                  " %5d/%c%c/%c%c%c %5Zd\n",
                                   i,
                                   q->flags,
                                   atomic_read(&q->use_count),
@@ -239,42 +253,46 @@ static int _drm_queues_info(char *buf, char **start, off_t offset, int len,
                                   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));
+                                  DRM_BUFCOUNT(&q->waitlist));
                atomic_dec(&q->use_count);
        }
-       
-       return len;
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_queues_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 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, len, eof, data);
+       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/drm/<dev>/bufs. */
+   /dev/dri/<dev>/bufs. */
 
-static int _drm_bufs_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 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)       return 0;
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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)
@@ -298,31 +316,39 @@ static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
        }
        DRM_PROC_PRINT("\n");
 
-       return len;
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_bufs_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 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, len, eof, data);
+       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 len,
-                            int *eof, void *data)
+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 > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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",
@@ -334,17 +360,19 @@ static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
                               priv->ioctl_count);
        }
 
-       return len;
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_clients_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 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, len, eof, data);
+       ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
        up(&dev->struct_sem);
        return ret;
 }
@@ -353,10 +381,11 @@ static int drm_clients_info(char *buf, char **start, off_t offset, int len,
 
 #define DRM_VMA_VERBOSE 0
 
-static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
-                        int *eof, void *data)
+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
@@ -370,9 +399,14 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
        unsigned int          pgprot;
 #endif
 
-       if (offset > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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));
@@ -389,7 +423,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
                               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",
@@ -402,7 +436,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
                               pgprot & _PAGE_DIRTY    ? 'd' : '-',
                               pgprot & _PAGE_PSE      ? 'm' : 'k',
                               pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
-#endif         
+#endif
                DRM_PROC_PRINT("\n");
 #if 0
                for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
@@ -427,18 +461,20 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
                }
 #endif
        }
-       
-       return len;
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_vma_info(char *buf, char **start, off_t offset, int len,
-                       int *eof, void *data)
+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, len, eof, data);
+       ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
        up(&dev->struct_sem);
        return ret;
 }
@@ -446,36 +482,42 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int len,
 
 
 #if DRM_DMA_HISTOGRAM
-static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
-                          int *eof, void *data)
+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 > 0) return 0; /* no partial requests */
-       len  = 0;
-       *eof = 1;
+       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->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));
+       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));
@@ -498,7 +540,8 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
                               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);
@@ -512,7 +555,7 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
                        DRM_PROC_PRINT("this_buffer    none\n");
                }
        }
-       
+
 
        DRM_PROC_PRINT("\nvalues:\n");
        if (dev->lock.hw_lock) {
@@ -529,8 +572,8 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
        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");
@@ -540,14 +583,14 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
                               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
@@ -560,17 +603,20 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
                prev_value = slot_value;
                slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
        }
-       return len;
+
+       if (len > request + offset) return request;
+       *eof = 1;
+       return len - offset;
 }
 
-static int drm_histo_info(char *buf, char **start, off_t offset, int len,
-                         int *eof, void *data)
+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, len, eof, data);
+       ret = DRM(_histo_info)(buf, start, offset, request, eof, data);
        up(&dev->struct_sem);
        return ret;
 }
diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c
new file mode 100644 (file)
index 0000000..ed37af4
--- /dev/null
@@ -0,0 +1,142 @@
+/* drm_stub.c -- -*- 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 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);
+               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)
+{
+       if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) {
+                               /* Already registered */
+               struct drm_stub_info *i;
+               i = (struct drm_stub_info *)inter_module_get("drm");
+               DRM(stub_info).info_register   = i->info_register;
+               DRM(stub_info).info_unregister = i->info_unregister;
+       } else {
+               DRM(stub_info).info_register   = DRM(stub_getminor);
+               DRM(stub_info).info_unregister = DRM(stub_putminor);
+               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;
+}
similarity index 84%
rename from linux/vm.c
rename to linux-core/drm_vm.c
index 964921b..347816a 100644 (file)
@@ -1,5 +1,5 @@
-/* vm.c -- Memory mapping for DRM -*- linux-c -*-
- * Created: Mon Jan  4 08:58:31 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #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,
+       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,
+       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,
+       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,
+       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)
+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)
+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)
+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)
+struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
+                               unsigned long address,
+                               int write_access)
 #endif
 {
 #if LINUX_VERSION_CODE >= 0x020300
@@ -105,14 +105,14 @@ struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
 }
 
 #if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
-                                    unsigned long address,
-                                    int write_access)
+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)
+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;
@@ -138,14 +138,14 @@ struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
 }
 
 #if LINUX_VERSION_CODE < 0x020317
-unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
-                               unsigned long address,
-                               int write_access)
+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)
+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;
@@ -172,7 +172,7 @@ struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
 #endif
 }
 
-void drm_vm_open(struct vm_area_struct *vma)
+void DRM(vm_open)(struct vm_area_struct *vma)
 {
        drm_file_t      *priv   = vma->vm_file->private_data;
        drm_device_t    *dev    = priv->dev;
@@ -190,7 +190,7 @@ void drm_vm_open(struct vm_area_struct *vma)
 
 
 #if DRM_DEBUG_CODE
-       vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
+       vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
        if (vma_entry) {
                down(&dev->struct_sem);
                vma_entry->vma  = vma;
@@ -202,7 +202,7 @@ void drm_vm_open(struct vm_area_struct *vma)
 #endif
 }
 
-void drm_vm_close(struct vm_area_struct *vma)
+void DRM(vm_close)(struct vm_area_struct *vma)
 {
        drm_file_t      *priv   = vma->vm_file->private_data;
        drm_device_t    *dev    = priv->dev;
@@ -226,7 +226,7 @@ void drm_vm_close(struct vm_area_struct *vma)
                        } else {
                                dev->vmalist = pt->next;
                        }
-                       drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+                       DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
                        break;
                }
        }
@@ -234,13 +234,13 @@ void drm_vm_close(struct vm_area_struct *vma)
 #endif
 }
 
-int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+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;
@@ -256,28 +256,28 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
 
        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);
+       DRM(vm_open)(vma);
        return 0;
 }
 
-int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+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);
+       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
@@ -290,14 +290,14 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
                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__)
@@ -365,6 +365,6 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
        ++filp->f_count;
 #endif
        vma->vm_file  =  filp;  /* Needed for drm_vm_open() */
-       drm_vm_open(vma);
+       DRM(vm_open)(vma);
        return 0;
 }
index aa824a7..8585fef 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 */
@@ -107,14 +108,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 +132,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 +167,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();
 
@@ -196,9 +197,9 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
                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;
@@ -222,15 +223,15 @@ 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(&current->mm->mmap_sem);
 #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(&current->mm->mmap_sem);
@@ -241,7 +242,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 +256,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 +264,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 +276,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 +305,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 +341,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 +359,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,7 +367,7 @@ 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);
@@ -380,7 +381,7 @@ static int i810_freelist_init(drm_device_t *dev)
        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,20 +390,20 @@ 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)
 {
@@ -417,27 +418,27 @@ static int i810_dma_initialize(drm_device_t *dev,
                DRM_ERROR("ring_map or buffer_map are invalid\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 *)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) {
                i810_dma_cleanup(dev);
                DRM_ERROR("can not ioremap virtual address for"
@@ -454,8 +455,8 @@ 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);
@@ -465,10 +466,10 @@ static int i810_dma_initialize(drm_device_t *dev,
                return -ENOMEM;
        }
        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) {
                i810_dma_cleanup(dev);
@@ -487,13 +488,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 +506,7 @@ int i810_dma_init(struct inode *inode, struct file *filp,
                        retcode = -EINVAL;
                break;
        }
-   
+
        return retcode;
 }
 
@@ -517,9 +518,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 +538,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 +570,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 +586,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 +652,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 +685,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 +700,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 +713,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 +745,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 +757,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 +767,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 +785,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 +822,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 +830,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);
        }
 
@@ -876,15 +877,15 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
 {
        drm_device_t     *dev = (drm_device_t *)device;
        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);
 }
@@ -902,9 +903,9 @@ 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);
@@ -912,14 +913,14 @@ int i810_irq_install(drm_device_t *dev, int irq)
        }
        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;
@@ -933,7 +934,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
        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 */
@@ -955,7 +956,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
        temp = I810_READ16(I810REG_INT_ENABLE_R);
        temp = temp & 0x6000;
        temp = temp | 0x0003;
-       I810_WRITE16(I810REG_INT_ENABLE_R, 
+       I810_WRITE16(I810REG_INT_ENABLE_R,
                     temp); /* Enable bp & user interrupts */
        return 0;
 }
@@ -972,20 +973,20 @@ int i810_irq_uninstall(drm_device_t *dev)
        irq      = dev->irq;
        dev->irq = 0;
        up(&dev->struct_sem);
-       
+
        if (!irq) return -EINVAL;
 
-       DRM_DEBUG(  "Interrupt UnInstall: %d\n", irq);  
+       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, 
+       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, 
+       I810_WRITE16(I810REG_INT_ENABLE_R,
                     temp);                     /* Disable all interrupts */
 
        free_irq(irq, dev);
@@ -1000,12 +1001,12 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
        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)))
@@ -1057,11 +1058,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 +1070,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 +1078,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 +1097,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 +1112,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 +1127,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 +1155,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 +1168,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 +1193,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)))
@@ -1286,15 +1208,15 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
        DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
                  vertex.idx, vertex.used, vertex.discard);
 
-       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;
 }
 
@@ -1309,14 +1231,14 @@ 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, 
+       i810_dma_dispatch_clear( dev, clear.flags,
+                                clear.clear_color,
                                 clear.clear_depth );
        return 0;
 }
@@ -1326,7 +1248,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)) {
@@ -1345,8 +1267,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;
@@ -1361,18 +1283,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);
@@ -1395,8 +1317,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;
@@ -1405,7 +1327,7 @@ 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;
 
index 7152eac..5b4d1c3 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 },
-
-       [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 },
-
-       [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 },
-
-       [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 },
-
-       [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 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");
-
-#ifndef MODULE
-/* i810_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)
-{
-       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)]);
-#endif
-
-       unblock_all_signals();
-       return 0;
-}
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "i810"
+#define DRIVER_DESC            "Intel i810"
+#define DRIVER_DATE            "20010215"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      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 },
+
+#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 __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       i810_dma_quiescent( dev );                                      \
+} while (0)
+
+#define __HAVE_RELEASE         1
+#define DRIVER_RELEASE() do {                                          \
+       i810_reclaim_buffers( dev, priv->pid );                         \
+} while (0)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_i810_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+({                                                                     \
+       drm_i810_private_t *dev_priv = (dev)->dev_private;              \
+       drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx];      \
+       map;                                                            \
+})
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 1c95740..e782409 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
@@ -67,25 +67,15 @@ 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,
@@ -101,44 +91,15 @@ extern int  i810_dma_init(struct inode *inode, struct file *filp,
 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
 
@@ -184,7 +145,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 +183,3 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
 
 
 #endif
-
index d1c39e9..b498a3e 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       1
-#define MGA_PATCHLEVEL  1
-
-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,
-};
-
-static struct miscdevice      mga_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  MGA_NAME,
-       fops:  &mga_fops,
-};
-
-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 },
-
-       [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 },
-
-       [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 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_blit,        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");
-
-#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.
- */
-
-static int __init mga_options(char *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);
-#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;
-}
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "mga"
+#define DRIVER_DESC            "Matrox G200/G400"
+#define DRIVER_DATE            "20010212"
+
+#define DRIVER_MAJOR           3
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#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 },
+
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+
+#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)
+
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) mga_do_cleanup_dma( dev );              \
+} while (0)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_mga_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_mga_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 cd5c0e8..08de203 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"
 
-#define R128_NAME              "r128"
-#define R128_DESC              "ATI Rage 128"
-#define R128_DATE              "20010130"
-#define R128_MAJOR             2
-#define R128_MINOR             1
-#define R128_PATCHLEVEL                4
-
-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 },
-#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_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_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");
-
-#ifndef MODULE
-/* r128_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)
-{
-       drm_parse_options(str);
-       return 1;
-}
-
-__setup("r128=", 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);
-
-       /* Force the cleanup of page flipping when required */
-       if ( dev->dev_private ) {
-               drm_r128_private_t *dev_priv = dev->dev_private;
-               if ( dev_priv->page_flipping ) {
-                       r128_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 r128_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return retcode;
-}
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "r128"
+#define DRIVER_DESC            "ATI Rage 128"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           2
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      4
+
+#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 },
 
-/* 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);
-               }
-       }
-
-       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;
-}
+/* 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
+
+#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)
+
+#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)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_r128_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_r128_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 0113ed9..da04610 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"
 
-#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 },
-#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");
-
-#ifndef MODULE
-/* radeon_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)
-{
-       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. */
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "radeon"
+#define DRIVER_DESC            "ATI Radeon"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#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_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 },
 
-       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);
-#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;
-}
+/* 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
+
+#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)
+
+#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)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_radeon_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_radeon_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 b98a298..9bb7b84 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       "20001030"
-#define TDFX_MAJOR      1
-#define TDFX_MINOR      0
-#define TDFX_PATCHLEVEL  0
-
-static drm_device_t          tdfx_device;
-drm_ctx_t                    tdfx_res_ctx;
-
-static struct file_operations tdfx_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#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_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 },
-
-       [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");
-
-#ifndef MODULE
-/* tdfx_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)
-{
-       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;
-       }
-#endif
 
-       unblock_all_signals();
-       return 0;
-}
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "tdfx"
+#define DRIVER_DESC            "3dfx Banshee/Voodoo3+"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#include "drm_drv.h"
+
+
+#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_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 9fe0038..a39b3cc 100644 (file)
@@ -62,7 +62,7 @@ obj-$(CONFIG_DRM_MGA)    += mga.o
 obj-$(CONFIG_DRM_I810)   += i810.o
 
 
-# When linking into the kernel, link the library just once. 
+# 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))
@@ -75,7 +75,7 @@ endif
 
 include $(TOPDIR)/Rules.make
 
-$(patsubst %.o,%.c,$(lib-objs-mod)): 
+$(patsubst %.o,%.c,$(lib-objs-mod)):
        @ln -sf $(subst -mod,,$@) $@
 
 drmlib-mod.a: $(lib-objs-mod)
index 1dd65e5..b5aca0a 100644 (file)
@@ -23,7 +23,7 @@
 # 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.
-# 
+#
 #
 # ***** NOTE NOTE NOTE NOTE NOTE *****
 # To override the automatic Linux source tree determination, pass the
 # **** End of SMP/MODVERSIONS detection
 
 MODS=           gamma.o tdfx.o
-LIBS=           libdrm.a
-
-DRMOBJS=       init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
-               lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
+LIBS=
+
+#DRMOBJS=      init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
+#              lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
+DRMOBS=
+DRMTEMPLATES=  drm_init.h drm_memory.h drm_proc.h drm_auth.h drm_context.h \
+               drm_drawable.h drm_bufs.h drm_lists.h drm_lock.h drm_ioctl.h \
+               drm_fops.h drm_vm.h drm_dma.h drm_stub.h
 DRMHEADERS=    drm.h drmP.h compat-pre24.h
 
-GAMMAOBJS=      gamma_drv.o gamma_dma.o
-GAMMAHEADERS=   gamma_drv.h $(DRMHEADERS)
+GAMMAOBJS=      gamma_drv.o gamma_drm.o gamma_dma.o gamma_context.o
+GAMMAHEADERS=   gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
 
-TDFXOBJS=       tdfx_drv.o tdfx_context.o
-TDFXHEADERS=    tdfx_drv.h $(DRMHEADERS)
+TDFXOBJS=       tdfx_drv.o
+TDFXHEADERS=    tdfx.h $(DRMHEADERS)
 
 INC=           /usr/include
 
@@ -71,7 +75,8 @@ MODCFLAGS=      $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer
 PRGCFLAGS=      $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
                -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
                -I../../../../../../include -I../../../../../../../../include \
-               -I../../../../../../../../programs/Xserver/hw/xfree86/common
+               -I../../../../../../../../programs/Xserver/hw/xfree86/common \
+               -I. -I../../.. -I../../../../../../../../lib/X11
 PRGLIBS=
 
 # **** Start of SMP/MODVERSIONS detection
@@ -128,7 +133,7 @@ endif
 
 ifeq ($(AGP),1)
 MODCFLAGS += -DCONFIG_AGP -DCONFIG_AGP_MODULE
-DRMOBJS += agpsupport.o
+#DRMOBJS += agpsupport.o
 MODS += mga.o r128.o radeon.o
 ifeq ($(MACHINE),i386)
 MODS += i810.o
@@ -138,18 +143,18 @@ MODS += i810.o
 endif
 
 
-MGAOBJS=       mga_drv.o mga_dma.o mga_bufs.o mga_context.o mga_state.o
-MGAHEADERS=    mga_drv.h $(DRMHEADERS)
+MGAOBJS=       mga_drv.o mga_dma.o mga_state.o mga_warp.o
+MGAHEADERS=    mga.h mga_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
 
-I810OBJS=      i810_drv.o i810_dma.o i810_bufs.o i810_context.o
-I810HEADERS=   i810_drv.h $(DRMHEADERS)
+I810OBJS=      i810_drv.o i810_dma.o
+I810HEADERS=   i810.h i810_drv.h $(DRMHEADERS) $(DRMTEMPLATES)
 
-R128OBJS=      r128_drv.o r128_cce.o r128_bufs.o r128_context.o r128_state.o
-R128HEADERS=   r128_drv.h r128_drm.h $(DRMHEADERS)
+R128OBJS=      r128_drv.o r128_cce.o r128_state.o
+R128HEADERS=   r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES)
 
-RADEONOBJS=    radeon_drv.o radeon_cp.o radeon_bufs.o radeon_context.o \
-               radeon_state.o
-RADEONHEADERS= radeon_drv.h radeon_drm.h $(DRMHEADERS)
+RADEONOBJS=    radeon_drv.o radeon_cp.o radeon_state.o
+RADEONHEADERS= radeon.h radeon_drv.h radeon_drm.h $(DRMHEADERS) \
+               $(DRMTEMPLATES)
 endif
 
 ifeq ($(SIS),1)
@@ -203,9 +208,12 @@ libdrm.a: $(DRMOBJS)
        -$(RM) -f $@
        $(AR) rcs $@ $(DRMOBJS)
 
+dristat: dristat.c
+       $(CC) $(PRGCFLAGS) $< -o $@
+
 gamma_drv.o: gamma_drv.c
        $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-gamma.o: $(GAMMAOBJS) $(LIBS)
+gamma.o: $(GAMMAOBJS)
        $(LD) -r $^ -o $@
 
 tdfx_drv.o: tdfx_drv.c
@@ -219,7 +227,7 @@ sis.o: $(SISOBJS) $(LIBS)
 ifeq ($(AGP),1)
 mga_drv.o: mga_drv.c
        $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@
-mga.o: $(MGAOBJS) $(LIBS)
+mga.o: $(MGAOBJS)
        $(LD) -r $^ -o $@
 
 i810_drv.o: i810_drv.c
diff --git a/linux/bufs.c b/linux/bufs.c
deleted file mode 100644 (file)
index 28e0eb5..0000000
+++ /dev/null
@@ -1,537 +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 */
-       }
-       
-       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(&current->mm->mmap_sem);
-               virtual = do_mmap(filp, 0, dma->byte_count,
-                                 PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-               up(&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/linux/ctxbitmap.c b/linux/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);
-}
-
index dc3d262..470eb03 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,6 +35,7 @@
 #ifndef _DRM_H_
 #define _DRM_H_
 
+#include <linux/config.h>
 #if defined(__linux__)
 #include <asm/ioctl.h>         /* For _IO* macros */
 #define DRM_IOCTL_NR(n)             _IOC_NR(n)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC   "/proc/misc"
-#define DRM_PROC_DRM    "/proc/drm"
-#define DRM_DEV_DRM     "/dev/drm"
 #define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID     0
 #define DRM_DEV_GID     0
 
-
+#define DRM_MAJOR       226
 #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                 */
@@ -72,12 +69,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"
@@ -150,6 +155,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        */
@@ -309,6 +352,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)
@@ -345,17 +391,18 @@ 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 */
+/* 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)
index 9a8fe61..58d98f5 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>
- *
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 #ifndef _DRM_P_H_
 #endif
 #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_DMA
+#define __HAVE_DMA             0
+#endif
+#ifndef __HAVE_DMA_WAITLIST
+#define __HAVE_DMA_WAITLIST    0
+#endif
+#ifndef __HAVE_DMA_FREELIST
+#define __HAVE_DMA_FREELIST    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_MEM_TOTALAGP  16
 #define DRM_MEM_BOUNDAGP  17
 #define DRM_MEM_CTXBITMAP 18
+#define DRM_MEM_STUB      19
 
 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
 
@@ -259,16 +286,16 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
        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)
@@ -276,22 +303,22 @@ 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; return len; }
+#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 )
+       (map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
 
 #define DRM_IOREMAPFREE(map)                                           \
        do {                                                            \
                if ( (map)->handle && (map)->size )                     \
-                       drm_ioremapfree( (map)->handle, (map)->size );  \
+                       DRM(ioremapfree)( (map)->handle, (map)->size ); \
        } while (0)
 
 #define DRM_FIND_MAP(map, o)                                           \
@@ -314,8 +341,8 @@ 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);
+typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg );
 
 typedef struct drm_ioctl_desc {
        drm_ioctl_t          *func;
@@ -463,9 +490,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    */
@@ -479,6 +508,7 @@ 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               */
@@ -492,6 +522,7 @@ 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;
@@ -501,7 +532,7 @@ typedef struct drm_device_dma {
        unsigned long     *pagelist;
        unsigned long     byte_count;
        enum {
-          _DRM_DMA_USE_AGP = 0x01
+               _DRM_DMA_USE_AGP = 0x01
        } flags;
 
                                /* DMA support */
@@ -511,7 +542,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;
@@ -559,17 +590,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;
@@ -617,7 +641,7 @@ typedef struct drm_device {
        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
        unsigned long     *ctx_bitmap;
@@ -630,227 +654,262 @@ typedef struct drm_device {
                                /* Internal function definitions */
 
                                /* Misc. support (init.c) */
-extern int          drm_flags;
-extern void         drm_parse_options(char *s);
-extern int           drm_cpu_valid(void);
+extern int          DRM(flags);
+extern void         DRM(parse_options)( char *s );
+extern int           DRM(cpu_valid)( void );
 
+                               /* 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);
 
                                /* 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);
+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 (vm.c) */
 #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_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,
+                                       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,
+extern struct page *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,
-                                     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);
+#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);
+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);
 
                                /* 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(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,
-                                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);
-#endif
-
-
                                /* 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,
+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);
 
-
                                /* 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,
-                                  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(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);
 
                                /* Drawable IOCTL support (drawable.c) */
-extern int          drm_adddraw(struct inode *inode, struct file *filp,
+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);
-extern int          drm_rmdraw(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,
-                                 unsigned int cmd, unsigned long arg);
-extern int          drm_authmagic(struct inode *inode, struct file *filp,
+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(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,
-                                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,
+extern int          DRM(block)(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);
+extern int          DRM(unblock)(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(ctxbitmap_init)( drm_device_t *dev );
+extern void         DRM(ctxbitmap_cleanup)( drm_device_t *dev );
 
-#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+
+
+
+                               /* 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,
+                                  unsigned int cmd, unsigned long arg );
+
+
+#if __HAVE_DMA
+                               /* DMA support (dma.c) */
+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);
+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);
+#if 0
+extern int          DRM(dma_get_buffers)(drm_device_t *dev, drm_dma_t *dma);
+#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
+#endif
+
+                               /* Buffer list management support (lists.c) */
+#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
+
+#if __REALLY_HAVE_AGP
                                /* 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,
+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);
+
+                               /* 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);
+
 #endif
 #endif
 #endif
diff --git a/linux/drm_agpsupport.h b/linux/drm_agpsupport.h
new file mode 100644 (file)
index 0000000..b070a59
--- /dev/null
@@ -0,0 +1,335 @@
+/* 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->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_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->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;
+               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/linux/drm_auth.h b/linux/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/linux/drm_bufs.h b/linux/drm_bufs.h
new file mode 100644 (file)
index 0000000..f2613a9
--- /dev/null
@@ -0,0 +1,757 @@
+/* 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 "drmP.h"
+
+#ifndef __HAVE_PCI_DMA
+#define __HAVE_PCI_DMA         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;
+
+       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 __REALLY_HAVE_AGP
+       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;
+}
+
+#if __HAVE_DMA
+
+#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;
+
+       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 */
+       }
+
+       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 );
+               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
+               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 );
+
+       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 = 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 );
+
+/* GH: Please leave this disabled for now.  I need to fix this properly...
+ */
+#if 0
+       /* FIXME: work this mess out...
+        */
+       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;
+
+       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 */
+       }
+
+       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 ) {
+               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 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 = 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);
+
+/* GH: Please leave this disabled for now.  I need to fix this properly...
+ */
+#if 0
+       /* FIXME: work this mess out...
+        */
+       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 */
+
+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_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) ) {
+                       drm_map_t *map = DRIVER_AGP_BUFFERS_MAP( dev );
+
+                       if ( !map ) {
+                               retcode = -EINVAL;
+                               goto done;
+                       }
+
+                       down( &current->mm->mmap_sem );
+                       virtual = do_mmap( filp, 0, map->size,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED,
+                                          (unsigned long)map->offset );
+                       up( &current->mm->mmap_sem );
+               } else {
+                       down( &current->mm->mmap_sem );
+                       virtual = do_mmap( filp, 0, dma->byte_count,
+                                          PROT_READ | PROT_WRITE,
+                                          MAP_SHARED, 0 );
+                       up( &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;
+}
+
+#endif /* __HAVE_DMA */
diff --git a/linux/drm_context.h b/linux/drm_context.h
new file mode 100644 (file)
index 0000000..6bbcfca
--- /dev/null
@@ -0,0 +1,270 @@
+/* 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>
+ */
+
+/* ================================================================
+ * Context bitmap support
+ */
+
+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 );
+}
+
+
+/* ================================================================
+ * 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 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 ) {
+                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 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 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;
+}
diff --git a/linux/drm_dma.h b/linux/drm_dma.h
new file mode 100644 (file)
index 0000000..35eb896
--- /dev/null
@@ -0,0 +1,576 @@
+/* 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
+
+#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 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)
+{
+       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 ( __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
+
+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 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;
+}
+
+#endif
+
+#endif
diff --git a/linux/drm_drawable.h b/linux/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/linux/drm_drv.h b/linux/drm_drv.h
new file mode 100644 (file)
index 0000000..b24d213
--- /dev/null
@@ -0,0 +1,927 @@
+/* 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 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_IOCTLS
+#define DRIVER_IOCTLS
+#endif
+
+
+static drm_device_t    DRM(device);
+static int              DRM(minor);
+
+static struct file_operations  DRM(fops) = {
+#if LINUX_VERSION_CODE >= 0x020400
+                               /* This started being used during 2.4.0-test */
+       owner:   THIS_MODULE,
+#endif
+       open:    DRM(open),
+       flush:   DRM(flush),
+       release: DRM(release),
+       ioctl:   DRM(ioctl),
+       mmap:    DRM(mmap),
+       read:    DRM(read),
+       fasync:  DRM(fasync),
+       poll:    DRM(poll),
+};
+
+
+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_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
+
+       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" );
+
+#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.
+ */
+
+static int __init DRM(options)( char *str )
+{
+       DRM(parse_options)( str );
+       return 1;
+}
+
+__setup( DRIVER_NAME "=", DRM(options) );
+#endif
+
+static int DRM(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 );
+
+#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 = 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 DRM(takedown)( drm_device_t *dev )
+{
+       drm_magic_entry_t *pt, *next;
+       drm_map_t *map;
+       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;
+       }
+
+                               /* 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:
+#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:
+                               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 __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;
+}
+
+/* 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 = &DRM(device);
+#if __HAVE_CTX_BITMAP
+       int retcode;
+#endif
+       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)( drm_opts );
+#endif
+       DRIVER_PREINIT();
+
+       DRM(mem_init)();
+
+       if ((DRM(minor) = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0)
+               return -EPERM;
+       dev->device = MKDEV(DRM_MAJOR, DRM(minor) );
+       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));
+               DRM(takedown)( dev );
+               return -ENOMEM;
+       }
+#endif
+#if __REALLY_HAVE_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 __HAVE_CTX_BITMAP
+       retcode = DRM(ctxbitmap_init)( dev );
+       if( retcode ) {
+               DRM_ERROR( "Cannot allocate memory for context bitmap.\n" );
+               DRM(stub_unregister)(DRM(minor));
+               DRM(takedown)( dev );
+               return retcode;
+       }
+#endif
+
+       DRIVER_POSTINIT();
+
+       DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
+                 DRIVER_NAME,
+                 DRIVER_MAJOR,
+                 DRIVER_MINOR,
+                 DRIVER_PATCHLEVEL,
+                 DRIVER_DATE,
+                 DRM(minor) );
+
+       return 0;
+}
+
+/* drm_cleanup is called via cleanup_module at module unload time.
+ */
+static void __exit drm_cleanup( void )
+{
+       drm_device_t *dev = &DRM(device);
+
+       DRM_DEBUG( "\n" );
+
+       if ( DRM(stub_unregister)(DRM(minor)) ) {
+               DRM_ERROR( "Cannot unload module\n" );
+       } else {
+               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 ) {
+               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
+}
+
+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 = &DRM(device);
+       int retcode = 0;
+
+       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_ERROR( "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 );
+               }
+       }
+#else
+       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 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 __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
+        }
+
+        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 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/linux/drm_fops.h b/linux/drm_fops.h
new file mode 100644 (file)
index 0000000..d646f31
--- /dev/null
@@ -0,0 +1,252 @@
+/* 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);
+       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;
+}
+
+#if 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;
+}
+#endif
+
+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/linux/drm_init.h b/linux/drm_init.h
new file mode 100644 (file)
index 0000000..9ae9841
--- /dev/null
@@ -0,0 +1,112 @@
+/* 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"
+
+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__)
+       return 0; /* No cmpxchg before v9 sparc. */
+#endif
+       return 1;
+}
diff --git a/linux/drm_ioctl.h b/linux/drm_ioctl.h
new file mode 100644 (file)
index 0000000..ce6ac2e
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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)
+               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;
+}
+
+
+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;
+       int          idx;
+
+       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;
+       }
+       map.offset = dev->maplist[idx]->offset;
+       map.size   = dev->maplist[idx]->size;
+       map.type   = dev->maplist[idx]->type;
+       map.flags  = dev->maplist[idx]->flags;
+       map.handle = dev->maplist[idx]->handle;
+       map.mtrr   = dev->maplist[idx]->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;
+}
similarity index 78%
rename from linux/lists.c
rename to linux/drm_lists.h
index 60e66b8..b597ef7 100644 (file)
@@ -1,5 +1,5 @@
-/* lists.c -- Buffer list handling routines -*- linux-c -*-
- * Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
+/* 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.
  * 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>
  */
 
 #define __NO_VERSION__
 #include "drmP.h"
 
-int drm_waitlist_create(drm_waitlist_t *bl, int count)
+#if __HAVE_DMA_WAITLIST
+
+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->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];
@@ -47,12 +49,12 @@ int drm_waitlist_create(drm_waitlist_t *bl, int count)
        return 0;
 }
 
-int drm_waitlist_destroy(drm_waitlist_t *bl)
+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);
+       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;
@@ -61,8 +63,8 @@ int drm_waitlist_destroy(drm_waitlist_t *bl)
        return 0;
 }
 
-int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf)
-{                                                      
+int DRM(waitlist_put)(drm_waitlist_t *bl, drm_buf_t *buf)
+{
        int           left;
        unsigned long flags;
 
@@ -76,16 +78,16 @@ int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf)
        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 *DRM(waitlist_get)(drm_waitlist_t *bl)
 {
        drm_buf_t     *buf;
        unsigned long flags;
@@ -95,14 +97,18 @@ drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl)
        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)
+#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;
@@ -115,14 +121,14 @@ int drm_freelist_create(drm_freelist_t *bl, int count)
        return 0;
 }
 
-int drm_freelist_destroy(drm_freelist_t *bl)
+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)
+int DRM(freelist_put)(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
 {
        drm_device_dma_t *dma  = dev->dma;
 
@@ -138,15 +144,15 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
        if (!bl) return 1;
 #if DRM_DMA_HISTOGRAM
        buf->time_freed = get_cycles();
-       drm_histogram_compute(dev, buf);
+       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",
@@ -161,12 +167,12 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
        return 0;
 }
 
-static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
+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) {
@@ -176,7 +182,7 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
        buf       = bl->next;
        bl->next  = bl->next->next;
        spin_unlock(&bl->lock);
-       
+
        atomic_dec(&bl->count);
        buf->next = NULL;
        buf->list = DRM_LIST_NONE;
@@ -184,17 +190,17 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
                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 *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);
@@ -204,7 +210,7 @@ drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
                        for (;;) {
                                current->state = TASK_INTERRUPTIBLE;
                                if (!atomic_read(&bl->wfh)
-                                   && (buf = drm_freelist_try(bl))) break;
+                                   && (buf = DRM(freelist_try)(bl))) break;
                                schedule();
                                if (signal_pending(current)) break;
                        }
@@ -213,6 +219,8 @@ drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
                }
                return buf;
        }
-               
-       return drm_freelist_try(bl);
+
+       return DRM(freelist_try)(bl);
 }
+
+#endif /* __HAVE_DMA_FREELIST */
diff --git a/linux/drm_lock.h b/linux/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/linux/drm_memory.h b/linux/drm_memory.h
new file mode 100644 (file)
index 0000000..caf0539
--- /dev/null
@@ -0,0 +1,460 @@
+/* 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_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 defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
+#if __MUST_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
+#endif /* defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) */
diff --git a/linux/drm_proc.h b/linux/drm_proc.h
new file mode 100644 (file)
index 0000000..634673d
--- /dev/null
@@ -0,0 +1,623 @@
+/* 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 DRM_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 DRM_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;
+                               /* 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");
+       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);
+               }
+       }
+
+       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 DRM_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/linux/drm_stub.h b/linux/drm_stub.h
new file mode 100644 (file)
index 0000000..ed37af4
--- /dev/null
@@ -0,0 +1,142 @@
+/* drm_stub.c -- -*- 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 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);
+               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)
+{
+       if (register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops))) {
+                               /* Already registered */
+               struct drm_stub_info *i;
+               i = (struct drm_stub_info *)inter_module_get("drm");
+               DRM(stub_info).info_register   = i->info_register;
+               DRM(stub_info).info_unregister = i->info_unregister;
+       } else {
+               DRM(stub_info).info_register   = DRM(stub_getminor);
+               DRM(stub_info).info_unregister = DRM(stub_putminor);
+               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/linux/drm_vm.h b/linux/drm_vm.h
new file mode 100644 (file)
index 0000000..347816a
--- /dev/null
@@ -0,0 +1,370 @@
+/* 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_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;
+}
diff --git a/linux/gamma.h b/linux/gamma.h
new file mode 100644 (file)
index 0000000..5ca1f74
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __GAMMA_H__
+#define __GAMMA_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) gamma_##x
+
+#define __HAVE_MTRR            1
+#define __HAVE_PCI_DMA         1
+#define __HAVE_CTX_BITMAP      0
+#define __HAVE_MULTIPLE_DMA_QUEUES     1
+#define __HAVE_DMA_FLUSH               1
+#define __HAVE_DMA_QUEUE               0
+#define __HAVE_DMA_SCHEDULE            1
+#define __HAVE_DMA_WAITQUEUE           1
+#define __HAVE_DMA_WAITLIST    1
+#define __HAVE_DMA_FREELIST    1
+#define __HAVE_DMA             1
+#define __HAVE_OLD_DMA         1
+#define __HAVE_DMA_IRQ         1
+
+#endif
similarity index 91%
rename from linux/context.c
rename to linux/gamma_context.c
index 933fd0c..d94054a 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define __NO_VERSION__
+#include "gamma.h"
 #include "drmP.h"
 
 static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
@@ -59,7 +60,7 @@ static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
 
        q->flags = ctx->flags;
 
-       drm_waitlist_create(&q->waitlist, dev->dma->buf_count);
+       gamma_waitlist_create(&q->waitlist, dev->dma->buf_count);
 
        return 0;
 }
@@ -93,7 +94,7 @@ static int drm_alloc_queue(drm_device_t *dev)
                                /* Allocate a new queue */
        down(&dev->struct_sem);
        
-       queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+       queue = gamma_alloc(sizeof(*queue), DRM_MEM_QUEUES);
        memset(queue, 0, sizeof(*queue));
        atomic_set(&queue->use_count, 1);
        
@@ -104,7 +105,7 @@ static int drm_alloc_queue(drm_device_t *dev)
                dev->queue_slots *= 2;
                newslots = dev->queue_slots * sizeof(*dev->queuelist);
 
-               dev->queuelist = drm_realloc(dev->queuelist,
+               dev->queuelist = gamma_realloc(dev->queuelist,
                                             oldslots,
                                             newslots,
                                             DRM_MEM_QUEUES);
@@ -121,7 +122,7 @@ static int drm_alloc_queue(drm_device_t *dev)
        return dev->queue_count - 1;
 }
 
-int drm_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_ctx_res_t   res;
@@ -148,7 +149,7 @@ int drm_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
 }
 
 
-int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -169,7 +170,7 @@ int drm_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -203,7 +204,7 @@ int drm_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -235,7 +236,7 @@ int drm_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
                  unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -248,7 +249,7 @@ int drm_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return drm_context_switch(dev, dev->last_context, ctx.handle);
 }
 
-int drm_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
               unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -263,7 +264,7 @@ int drm_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
        return 0;
 }
 
-int drm_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
+int gamma_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
              unsigned long arg)
 {
        drm_file_t      *priv   = filp->private_data;
@@ -298,8 +299,8 @@ int drm_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
                }
        }
                                /* Remove queued buffers */
-       while ((buf = drm_waitlist_get(&q->waitlist))) {
-               drm_free_buffer(dev, buf);
+       while ((buf = gamma_waitlist_get(&q->waitlist))) {
+               gamma_free_buffer(dev, buf);
        }
        clear_bit(0, &dev->interrupt_flag);
        
index 4854c56..e2ac606 100644 (file)
  */
 
 #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>
+
+#if 0
+#define DO_IOREMAP( _map )                                             \
+do {                                                                   \
+       (_map)->handle = DRM(ioremap)( (_map)->offset, (_map)->size );  \
+} while (0)
+
+#define DO_IOREMAPFREE( _map )                                         \
+do {                                                                   \
+       if ( (_map)->handle && (_map)->size )                           \
+               DRM(ioremapfree)( (_map)->handle, (_map)->size );       \
+} while (0)
+
+#define DO_FIND_MAP( _map, _offset )                                   \
+do {                                                                   \
+       int _i;                                                         \
+       for ( _i = 0 ; _i < dev->map_count ; _i++ ) {                   \
+               if ( dev->maplist[_i]->offset == _offset ) {            \
+                       _map = dev->maplist[_i];                        \
+                       break;                                          \
+               }                                                       \
+       }                                                               \
+} while (0)
+#endif
 
 /* WARNING!!! MAGIC NUMBER!!!  The number of regions already added to the
    kernel must be specified here.  Currently, the number is 2. This must
@@ -88,7 +113,7 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
        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)
 {
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
@@ -104,7 +129,7 @@ static inline void gamma_dma_quiescent_single(drm_device_t *dev)
        } 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)
 {
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
@@ -129,7 +154,7 @@ 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)
 {
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
@@ -145,18 +170,15 @@ static 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);
+       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,10 +201,7 @@ 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();
@@ -202,16 +221,16 @@ 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;
        }
@@ -228,9 +247,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;
                }
@@ -241,8 +259,8 @@ static int gamma_do_dma(drm_device_t *dev, int locked)
                 & _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);
+                       gamma_clear_next_buffer(dev);
+                       gamma_free_buffer(dev, buf);
                }
                retcode = -EBUSY;
                goto cleanup;
@@ -254,7 +272,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 +281,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,7 +299,7 @@ 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;
@@ -313,10 +331,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 +351,19 @@ 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,
+                       next = gamma_select_queue(dev,
                                             gamma_dma_schedule_timer_wrapper);
                        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,12 +375,10 @@ 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;
                }
@@ -375,7 +387,7 @@ 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 +412,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 +422,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];
@@ -494,11 +505,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 +518,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");
                }
@@ -532,7 +543,7 @@ static int gamma_dma_send_buffers(drm_device_t *dev, drm_dma_t *d)
                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;
@@ -558,7 +569,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) {
@@ -585,21 +596,19 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
        int               retcode   = 0;
        drm_dma_t         d;
 
+#if 0
+       LOCK_TEST_WITH_RETURN( dev );
+#endif
+
        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);
@@ -616,7 +625,7 @@ int gamma_dma(struct inode *inode, struct file *filp, unsigned int cmd,
        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",
@@ -728,109 +737,3 @@ int gamma_control(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        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;
-}
diff --git a/linux/gamma_drm.c b/linux/gamma_drm.c
new file mode 100644 (file)
index 0000000..4b12d8c
--- /dev/null
@@ -0,0 +1,33 @@
+#define __NO_VERSION__
+#include "gamma.h"
+#include "drmP.h"
+#include "gamma_drv.h"
+
+#define DRIVER_DEV_PRIV_T      drm_gamma_private_t
+#define DRIVER_AGP_BUFFER_MAP  dev_priv->buffers
+
+#include "drm_auth.h"
+
+#include "drm_bufs.h"
+
+#include "drm_dma.h"
+
+#include "drm_drawable.h"
+
+#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 a17bc1a..79e8ad1 100644 (file)
  */
 
 #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
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "gamma"
+#define DRIVER_DESC            "3DLabs gamma"
+#define DRIVER_DATE            "20010208"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+
+#define DRIVER_IOCTLS                                                    \
+       [DRM_IOCTL_NR(DRM_IOCTL_DMA)]        = { gamma_dma,       1, 0 }
+
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      0
+#define __HAVE_PCI_DMA         1
+#define __HAVE_MULTIPLE_DMA_QUEUES     1
+#define __HAVE_DMA_FLUSH               1
+#define __HAVE_DMA_QUEUE               0
+#define __HAVE_DMA_SCHEDULE            1
+#define __HAVE_DMA_WAITQUEUE           1
+#define __HAVE_DMA_WAITLIST    1
+#define __HAVE_DMA_FREELIST    1
+#define __HAVE_DMA             1
+#define __HAVE_OLD_DMA         1
+#define __HAVE_DMA_IRQ         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
+
+#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)
+
+#if 0
+#define __HAVE_DRIVER_RELEASE  1
+#define DRIVER_RELEASE() do {                                          \
+       gamma_reclaim_buffers( dev, priv->pid );                        \
+       if ( dev->dev_private ) {                                       \
+               drm_gamma_private_t *dev_priv = dev->dev_private;       \
+               dev_priv->dispatch_status &= MGA_IN_DISPATCH;           \
+       }                                                               \
+} while (0)
 #endif
-#ifndef PCI_DEVICE_ID_3DLABS_MX
-#define PCI_DEVICE_ID_3DLABS_MX 0x0006
-#endif
-
-#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
-
-static drm_device_t          gamma_device;
-
-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,
-};
-
-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 },
-
-       [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)
-
-#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
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_options.
- */
-
-
-static int __init gamma_options(char *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);
-                               }
-#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 */
+#if 0
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) gamma_do_cleanup_dma( dev );            \
+} while (0)
 #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
+#include "drm_drv.h"
 
-       unblock_all_signals();
-       return 0;
-}
index e9ce395..1bfa265 100644 (file)
 #ifndef _GAMMA_DRV_H_
 #define _GAMMA_DRV_H_
 
+
+typedef struct drm_gamma_private {
+       drm_map_t *buffers;
+} 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_drv.c */
 extern int  gamma_version(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg);
diff --git a/linux/i810.h b/linux/i810.h
new file mode 100644 (file)
index 0000000..021d798
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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
+
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+
+#define __HAVE_MTRR            1
+
+#define __HAVE_CTX_BITMAP      1
+
+#define __HAVE_DMA             1
+#define __HAVE_DMA_IRQ         1
+#define __HAVE_DMA_QUEUE       1
+#define __HAVE_DMA_WAITLIST    1
+#define __HAVE_DMA_RECLAIM     1
+
+#endif
diff --git a/linux/i810_bufs.c b/linux/i810_bufs.c
deleted file mode 100644 (file)
index a999e96..0000000
+++ /dev/null
@@ -1,332 +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 */
-       }
-   
-       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/linux/i810_context.c b/linux/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 aa824a7..8585fef 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 */
@@ -107,14 +108,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 +132,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 +167,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();
 
@@ -196,9 +197,9 @@ static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
                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;
@@ -222,15 +223,15 @@ 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(&current->mm->mmap_sem);
 #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(&current->mm->mmap_sem);
@@ -241,7 +242,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 +256,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 +264,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 +276,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 +305,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 +341,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 +359,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,7 +367,7 @@ 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);
@@ -380,7 +381,7 @@ static int i810_freelist_init(drm_device_t *dev)
        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,20 +390,20 @@ 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)
 {
@@ -417,27 +418,27 @@ static int i810_dma_initialize(drm_device_t *dev,
                DRM_ERROR("ring_map or buffer_map are invalid\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 *)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) {
                i810_dma_cleanup(dev);
                DRM_ERROR("can not ioremap virtual address for"
@@ -454,8 +455,8 @@ 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);
@@ -465,10 +466,10 @@ static int i810_dma_initialize(drm_device_t *dev,
                return -ENOMEM;
        }
        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) {
                i810_dma_cleanup(dev);
@@ -487,13 +488,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 +506,7 @@ int i810_dma_init(struct inode *inode, struct file *filp,
                        retcode = -EINVAL;
                break;
        }
-   
+
        return retcode;
 }
 
@@ -517,9 +518,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 +538,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 +570,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 +586,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 +652,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 +685,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 +700,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 +713,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 +745,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 +757,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 +767,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 +785,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 +822,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 +830,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);
        }
 
@@ -876,15 +877,15 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
 {
        drm_device_t     *dev = (drm_device_t *)device;
        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);
 }
@@ -902,9 +903,9 @@ 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);
@@ -912,14 +913,14 @@ int i810_irq_install(drm_device_t *dev, int irq)
        }
        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;
@@ -933,7 +934,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
        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 */
@@ -955,7 +956,7 @@ int i810_irq_install(drm_device_t *dev, int irq)
        temp = I810_READ16(I810REG_INT_ENABLE_R);
        temp = temp & 0x6000;
        temp = temp | 0x0003;
-       I810_WRITE16(I810REG_INT_ENABLE_R, 
+       I810_WRITE16(I810REG_INT_ENABLE_R,
                     temp); /* Enable bp & user interrupts */
        return 0;
 }
@@ -972,20 +973,20 @@ int i810_irq_uninstall(drm_device_t *dev)
        irq      = dev->irq;
        dev->irq = 0;
        up(&dev->struct_sem);
-       
+
        if (!irq) return -EINVAL;
 
-       DRM_DEBUG(  "Interrupt UnInstall: %d\n", irq);  
+       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, 
+       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, 
+       I810_WRITE16(I810REG_INT_ENABLE_R,
                     temp);                     /* Disable all interrupts */
 
        free_irq(irq, dev);
@@ -1000,12 +1001,12 @@ int i810_control(struct inode *inode, struct file *filp, unsigned int cmd,
        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)))
@@ -1057,11 +1058,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 +1070,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 +1078,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 +1097,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 +1112,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 +1127,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 +1155,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 +1168,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 +1193,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)))
@@ -1286,15 +1208,15 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
        DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
                  vertex.idx, vertex.used, vertex.discard);
 
-       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;
 }
 
@@ -1309,14 +1231,14 @@ 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, 
+       i810_dma_dispatch_clear( dev, clear.flags,
+                                clear.clear_color,
                                 clear.clear_depth );
        return 0;
 }
@@ -1326,7 +1248,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)) {
@@ -1345,8 +1267,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;
@@ -1361,18 +1283,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);
@@ -1395,8 +1317,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;
@@ -1405,7 +1327,7 @@ 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;
 
index 7152eac..5b4d1c3 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 },
-
-       [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 },
-
-       [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 },
-
-       [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 },
-
-       [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 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");
-
-#ifndef MODULE
-/* i810_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)
-{
-       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)]);
-#endif
-
-       unblock_all_signals();
-       return 0;
-}
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "i810"
+#define DRIVER_DESC            "Intel i810"
+#define DRIVER_DATE            "20010215"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      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 },
+
+#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 __HAVE_DMA_QUIESCENT   1
+#define DRIVER_DMA_QUIESCENT() do {                                    \
+       i810_dma_quiescent( dev );                                      \
+} while (0)
+
+#define __HAVE_RELEASE         1
+#define DRIVER_RELEASE() do {                                          \
+       i810_reclaim_buffers( dev, priv->pid );                         \
+} while (0)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_i810_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+({                                                                     \
+       drm_i810_private_t *dev_priv = (dev)->dev_private;              \
+       drm_map_t *map = (dev)->maplist[dev_priv->buffer_map_idx];      \
+       map;                                                            \
+})
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 1c95740..e782409 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
@@ -67,25 +67,15 @@ 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,
@@ -101,44 +91,15 @@ extern int  i810_dma_init(struct inode *inode, struct file *filp,
 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
 
@@ -184,7 +145,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 +183,3 @@ int i810_clear_bufs(struct inode *inode, struct file *filp,
 
 
 #endif
-
diff --git a/linux/ioctl.c b/linux/ioctl.c
deleted file mode 100644 (file)
index 2f4286b..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)
-               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/linux/mga.h b/linux/mga.h
new file mode 100644 (file)
index 0000000..9b22240
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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
+
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+
+#define __HAVE_MTRR            1
+
+#define __HAVE_CTX_BITMAP      1
+
+#define __HAVE_DMA             1
+
+#endif
diff --git a/linux/mga_bufs.c b/linux/mga_bufs.c
deleted file mode 100644 (file)
index 05d941b..0000000
+++ /dev/null
@@ -1,612 +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 */
-       }
-   
-       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 */
-       }
-       
-       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(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size, 
-                                         PROT_READ|PROT_WRITE,
-                                         MAP_SHARED, 
-                                         (unsigned long)map->offset);
-                       up(&current->mm->mmap_sem);
-               } else {
-                       down(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
-                                         PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-                       up(&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/linux/mga_context.c b/linux/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 356376c..9fafa29 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 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 ) return 0;
+               udelay( 1 );
        }
-       atomic_inc(&virt_to_page(address)->count);
-       set_bit(PG_reserved, &virt_to_page(address)->flags);
 
-       return address;
+       DRM_DEBUG( "failed! status=0x%08x\n", status );
+       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 );
+       }
+
+       DRM_DEBUG( "failed! status=0x%08x\n", status );
+       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...
+        */
 
-       dev_priv->head = dev_priv->tail = NULL;
+       /* FIXME: What else do we need to reinitialize?  WARP stuff?
+        */
+
+       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;
-
-       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;
+       /* 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 );
+
+       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DMAPAD,  0x00000000 );
+
+       ADVANCE_DMA();
+
+       primary->last_flush = primary->tail;
+
+       head = *primary->head;
+
+       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_DWGSYNC, 0x12345678 );
 
-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 = *primary->head;
+
+       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 );
+
+       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__ );
 
-       /* 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);
+       sarea_priv->last_wrap++;
+       DRM_DEBUG( "   wrap = %d\n", sarea_priv->last_wrap );
 
-       dev_priv->current_prim = prim_buffer;
-       dev_priv->current_prim_idx = next_prim_idx;
-       return 0;
-}
+       *primary->head = head;
 
-/* More dynamic performance decisions */
-static inline int mga_decide_to_fire(drm_device_t *dev)
-{
-       drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
+       mga_flush_write_combine();
+       MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
 
-       if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
-               return 1;
-       }
+       DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
+}
 
-       if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
-           dev_priv->next_prim->num_dwords) {
-               return 1;
-       }
 
-       if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
-           dev_priv->next_prim->num_dwords) {
-               return 1;
-       }
+/* ================================================================
+ * Freelist management
+ */
 
-       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;
-               }
-       }
+#define MGA_BUFFER_USED                ~0
+#define MGA_BUFFER_FREE                0
 
-       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;
-               }
-       }
+static void mga_freelist_print( drm_device_t *dev )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       drm_mga_freelist_t *entry;
 
-       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;
-               }
-       }
+       DRM_INFO( "\n" );
+       DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
+                 dev_priv->sarea_priv->last_dispatch,
+                 *dev_priv->prim.head - dev_priv->primary->offset );
+       DRM_INFO( "current freelist:\n" );
 
-       return 0;
+       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" );
 }
 
-int mga_dma_schedule(drm_device_t *dev, int locked)
+static int mga_freelist_init( 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_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_freelist_t *entry;
+       int i;
+       DRM_INFO( "%s: count=%d\n",
+                 __FUNCTION__, dma->buf_count );
 
-       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;
-       }
+       dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
+                                    DRM_MEM_DRIVER );
+       if ( dev_priv->head == NULL )
+               return -ENOMEM;
 
-       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;
-       }
+       memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) );
+       SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 );
 
-       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);
-               }
-       }
+       for ( i = 0 ; i < dma->buf_count ; i++ ) {
+               buf = dma->buflist[i];
+               buf_priv = buf->dev_private;
 
-       if (!locked) {
-               if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
-                                 DRM_KERNEL_CONTEXT)) {
-                       DRM_ERROR("\n");
-               }
-       }
+               entry = DRM(alloc)( sizeof(drm_mga_freelist_t),
+                                   DRM_MEM_DRIVER );
+               if ( entry == NULL )
+                       return -ENOMEM;
 
-       clear_bit(0, &dev->dma_flag);
+               memset( entry, 0, sizeof(drm_mga_freelist_t) );
 
-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);
-       }
+               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;
 
-       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);
+               dev_priv->head->next = entry;
+       }
 
-       return retval;
+       return 0;
 }
 
-static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
+static void mga_freelist_cleanup( drm_device_t *dev )
 {
-       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_freelist_t *entry;
+       drm_mga_freelist_t *next;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       entry = dev_priv->head;
+       while ( entry ) {
+               next = entry->next;
+               DRM(free)( entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER );
+               entry = next;
+       }
+
+       dev_priv->head = dev_priv->tail = NULL;
 }
 
-static void mga_dma_task_queue(void *device)
+static void mga_freelist_reset( drm_device_t *dev )
 {
-       mga_dma_schedule((drm_device_t *)device, 0);
+       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;
+       int i;
+
+       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 );
+       }
 }
 
-int mga_dma_cleanup(drm_device_t *dev)
+static drm_buf_t *mga_freelist_get( drm_device_t *dev )
 {
-       if(dev->dev_private) {
-               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 *next;
+       drm_mga_freelist_t *prev;
+       drm_mga_freelist_t *tail = dev_priv->tail;
+       u32 head, wrap;
+       DRM_DEBUG( "%s:\n", __FUNCTION__ );
 
-               if (dev->irq) mga_flush_queue(dev);
-               mga_dma_quiescent(dev);
+       head = *dev_priv->prim.head;
+       wrap = dev_priv->sarea_priv->last_wrap;
 
-               if(dev_priv->ioremap) {
-                       int temp = (dev_priv->warp_ucode_size +
-                                   dev_priv->primary_size +
-                                   PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
+       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 );
 
-                       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);
-               }
+       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;
+       }
 
+       DRM_DEBUG( "returning NULL!\n" );
+       return NULL;
+}
 
-               drm_free(dev->dev_private, sizeof(drm_mga_private_t),
-                        DRM_MEM_DRIVER);
-               dev->dev_private = NULL;
+static int mga_freelist_put( 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_freelist_t *head, *next, *prev;
+
+       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 );
+
+       if ( buf_priv->list_entry->age.head == MGA_BUFFER_USED ) {
+               SET_AGE( &next->age, MGA_BUFFER_FREE, 0 );
        }
 
+       /* Put buffer on the head + 1, as the head is a sentinal.
+        */
+       next = buf_priv->list_entry;
+       head = dev_priv->head;
+       prev = head->next;
+       head->next = next;
+       prev->prev = next;
+       next->prev = head;
+       next->next = prev;
+
        return 0;
 }
 
-static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
+
+/* ================================================================
+ * DMA initialization, cleanup
+ */
+
+static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
+{
        drm_mga_private_t *dev_priv;
-       drm_map_t *sarea_map = NULL;
+       int ret;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-       dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
-       if(dev_priv == NULL) return -ENOMEM;
-       dev->dev_private = (void *) dev_priv;
+       dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
+       if ( !dev_priv )
+               return -ENOMEM;
+       dev->dev_private = (void *)dev_priv;
 
-       memset(dev_priv, 0, sizeof(drm_mga_private_t));
+       memset( dev_priv, 0, sizeof(drm_mga_private_t) );
 
-       if((init->reserved_map_idx >= dev->map_count) ||
-          (init->buffer_map_idx >= dev->map_count)) {
-               mga_dma_cleanup(dev);
-               return -EINVAL;
+       dev_priv->chipset = init->chipset;
+
+       dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
+
+       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;
 
-       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->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;
 
-       /* 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);
-               return -ENOMEM;
+       dev_priv->depth_cpp     = init->depth_cpp;
+       dev_priv->depth_offset  = init->depth_offset;
+       dev_priv->depth_pitch   = init->depth_pitch;
+
+       dev_priv->sarea = dev->maplist[0];
+
+       DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
+       DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
+       DRM_FIND_MAP( dev_priv->status, init->status_offset );
+
+       DRM_FIND_MAP( dev_priv->warp, init->warp_offset );
+       DRM_FIND_MAP( dev_priv->primary, init->primary_offset );
+       DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
+
+       dev_priv->sarea_priv =
+               (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
+                                   init->sarea_priv_offset);
+
+       DRM_IOREMAP( dev_priv->warp );
+       DRM_IOREMAP( dev_priv->primary );
+       DRM_IOREMAP( dev_priv->buffers );
+
+       ret = mga_warp_install_microcode( dev );
+       if ( ret < 0 ) {
+               DRM_ERROR( "failed to install WARP ucode!\n" );
+               mga_do_cleanup_dma( dev );
+               return ret;
        }
-       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_init( dev );
+       if ( ret < 0 ) {
+               DRM_ERROR( "failed to init WARP engine!\n" );
+               mga_do_cleanup_dma( dev );
+               return ret;
        }
 
-       dev_priv->status_page =
-               ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
-                               PAGE_SIZE);
+       dev_priv->prim.status = (u32 *)dev_priv->status->handle;
 
-       if(dev_priv->status_page == NULL) {
-               mga_dma_cleanup(dev);
-               DRM_ERROR("Can not remap status page\n");
-               return -ENOMEM;
-       }
+       mga_do_wait_for_idle( dev_priv );
+
+       /* Init the primary DMA registers.
+        */
+       MGA_WRITE( MGA_PRIMADDRESS,
+                  dev_priv->primary->offset | MGA_DMA_GENERAL );
+
+       MGA_WRITE( MGA_PRIMPTR,
+                  virt_to_bus((void *)dev_priv->prim.status) |
+                  MGA_PRIMPTREN0 |     /* Soft trap, SECEND, SETUPEND */
+                  MGA_PRIMPTREN1 );    /* DWGSYNC */
 
-       /* Write status page when secend or softrap occurs */
-       MGA_WRITE(MGAREG_PRIMPTR,
-                 virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
+       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.head = &dev_priv->prim.status[0];
+       dev_priv->prim.tail = 0;
+       dev_priv->prim.space = dev_priv->prim.size;
 
-       /* Private is now filled in, initialize the hardware */
-       {
-               PRIMLOCALS;
-               PRIMGETPTR( dev_priv );
+       dev_priv->prim.last_flush = 0;
+       dev_priv->prim.last_wrap = 0;
 
-               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
-                */
+       dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;
 
-               mga_flush_write_combine();
-               MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
+       spin_lock_init( &dev_priv->prim.list_lock );
 
-               MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
-                                          PDEA_pagpxfer_enable));
+       dev_priv->prim.status[0] = dev_priv->primary->offset;
+       dev_priv->prim.status[1] = 0;
 
-               while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
+       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 ) < 0 ) {
+               DRM_ERROR( "could not initialize freelist\n" );
+               mga_do_cleanup_dma( dev );
+               return -ENOMEM;
        }
 
-       if(mga_freelist_init(dev) != 0) {
-               DRM_ERROR("Could not initialize freelist\n");
-               mga_dma_cleanup(dev);
-               return -ENOMEM;
+       return 0;
+}
+
+int mga_do_cleanup_dma( drm_device_t *dev )
+{
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       if ( dev->dev_private ) {
+               drm_mga_private_t *dev_priv = dev->dev_private;
+
+               DRM_IOREMAPFREE( dev_priv->warp );
+               DRM_IOREMAPFREE( dev_priv->primary );
+               DRM_IOREMAPFREE( dev_priv->buffers );
+
+               if ( dev_priv->head != NULL ) {
+                       mga_freelist_cleanup( dev );
+               }
+
+               DRM(free)( dev->dev_private, sizeof(drm_mga_private_t),
+                          DRM_MEM_DRIVER );
+               dev->dev_private = NULL;
        }
+
        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_TEST_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 ) {
+               return mga_do_wait_for_idle( dev_priv );
+       } 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_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;
        }
 
-       if(lock.flags & _DRM_LOCK_FLUSH || lock.flags & _DRM_LOCK_FLUSH_ALL) {
-               drm_mga_prim_buf_t *temp_buf;
+       /* 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;
+       }
 
-               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 5381339..c2fe4a1 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:
- */
-#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
+ * defines in the Xserver file (mga_sarea.h)
  */
-#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                32
 
 /* 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,75 +191,119 @@ 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;
+
+       int 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 int fb_offset;
+       unsigned int mmio_offset;
+       unsigned int status_offset;
+       unsigned int warp_offset;
+       unsigned int primary_offset;
+       unsigned int 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_iload {
-       int idx;
-       int length;
-       unsigned int destOrg;
-} 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?  */
+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?  */
+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 {
+typedef struct drm_mga_iload {
+       int idx;
+       unsigned int dstorg;
+       unsigned int length;
+} drm_mga_iload_t;
+
+typedef struct drm_mga_blit {
        unsigned int planemask;
-       unsigned int source;
-       unsigned int dest;
+       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 d1c39e9..b498a3e 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       1
-#define MGA_PATCHLEVEL  1
-
-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,
-};
-
-static struct miscdevice      mga_misc = {
-       minor: MISC_DYNAMIC_MINOR,
-       name:  MGA_NAME,
-       fops:  &mga_fops,
-};
-
-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 },
-
-       [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 },
-
-       [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 },
-       [DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_blit,        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");
-
-#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.
- */
-
-static int __init mga_options(char *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);
-#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;
-}
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "mga"
+#define DRIVER_DESC            "Matrox G200/G400"
+#define DRIVER_DATE            "20010212"
+
+#define DRIVER_MAJOR           3
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#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 },
+
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+
+#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)
+
+#define DRIVER_PRETAKEDOWN() do {                                      \
+       if ( dev->dev_private ) mga_do_cleanup_dma( dev );              \
+} while (0)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_mga_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_mga_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 d7bf632..7a5a1dc 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;
+       volatile u32 *head;
+       u32 tail;
+       int space;
+
+       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;
+
+       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_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);
+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_lock( 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 );
 
                                /* 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_control( 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_irq_uninstall( drm_device_t *dev );
+
                                /* 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);
-extern int  mga_blit(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_device_t *dev );
+extern int mga_warp_init( drm_device_t *dev );
 
 #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 DWGREG0        0x1c00
 #define DWGREG0_END    0x1dff
@@ -202,328 +173,435 @@ 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 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 WRAP_TEST_WITH_RETURN( dev_priv )                              \
+do {                                                                   \
+       if ( dev_priv->sarea_priv->last_wrap <                          \
+            dev_priv->prim.last_wrap ) {                               \
+               if ( mga_do_wait_for_idle( dev_priv ) < 0 )             \
+                       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 FLUSH_DMA()                                                    \
+do {                                                                   \
+       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 ageing 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_SOFTRAP_SIZE           32 * DMA_BLOCK_SIZE
+
+
 
 /* A reduced set of the mga registers.
  */
 
-#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_SGN                              0x1c58
-#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 SO_srcacc_pci          0x0             
-#define SO_srcacc_agp          0x2             
-#define SO_srcmap_fb           0x0             
-#define SO_srcmap_sys          0x1             
-
-
-#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)
+#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
+
+/* 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)
 
 #endif
index bba8fa3..dc2c8c3 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_DEBUG( "*** 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,720 +420,642 @@ 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;
 
-       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;
+       org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
+
+       if ( org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI) ) {
+               DRM_DEBUG( "*** 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) ) {
                return -EINVAL;
        }
-       if (length % 64) {
+
+       if ( length & MGA_ILOAD_MASK ) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+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) ) {
                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 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;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->ContextState;
-       int use_agp = PDEA_pagpxfer_enable | 0x00000001;
-       u16 y2;
-       PRIMLOCALS;
+       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;
+       for ( i = 0 ; i < nbox ; i++ ) {
+               drm_clip_rect_t *box = &pbox[i];
+               u32 height = box->y2 - box->y1;
+
+               if ( clear->flags & MGA_FRONT ) {
+                       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->front_offset,
+                                  MGA_DWGCTL + MGA_EXEC,
+                                               dev_priv->clear_cmd );
+
+                       ADVANCE_DMA();
+               }
 
-       PRIM_OVERFLOW(dev, dev_priv, 30);
 
-       PRIMOUTREG(MGAREG_DSTORG, destOrg);
-       PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
-       PRIMOUTREG(MGAREG_SRCORG, (u32) bus_address | use_agp);
-       PRIMOUTREG(MGAREG_AR5, 64);
+               if ( clear->flags & MGA_BACK ) {
+                       BEGIN_DMA( 2 );
 
-       PRIMOUTREG(MGAREG_PITCH, 64);
-       PRIMOUTREG(MGAREG_PLNWT, ~0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+                       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_AR0, 63);
-       PRIMOUTREG(MGAREG_AR3, 0);
-       PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
-       PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
+                       DMA_BLOCK( MGA_DMAPAD,  0x00000000,
+                                  MGA_FCOL,    clear->clear_color,
+                                  MGA_DSTORG,  dev_priv->back_offset,
+                                  MGA_DWGCTL + MGA_EXEC,
+                                               dev_priv->clear_cmd );
 
-       PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]);
-       PRIMOUTREG(MGAREG_SRCORG, 0);
-       PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-       PRIMADVANCE(dev_priv);
+                       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_vertex(drm_device_t * dev, drm_buf_t * buf)
+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" );
+       DRM_DEBUG( "   head = 0x%06x\n", *dev_priv->prim.head );
+
+       sarea_priv->last_frame.head = dev_priv->prim.tail;
+       sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
+
+       DRM_DEBUG( "   tail = 0x%06x\n", dev_priv->prim.tail );
+       DRM_DEBUG( "   wrap = 0x%06x\n", 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;
+
+               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 )
 {
        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);
-       }
-       if (buf_priv->discard) {
-               if (buf_priv->dispatched == 1)
-                       AGEBUF(dev_priv, buf_priv);
-               buf_priv->dispatched = 0;
-               mga_freelist_put(dev, buf);
-       }
-}
+                       BEGIN_DMA( 1 );
 
+                       DMA_BLOCK( MGA_DMAPAD,          0x00000000,
+                                  MGA_DMAPAD,          0x00000000,
+                                  MGA_SETUPADDRESS,    address + start,
+                                  MGA_SETUPEND,        ((address + end) |
+                                                        MGA_PAGPXFER) );
 
-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)
-{
-       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);
-               }
+                       ADVANCE_DMA();
+               } while ( ++i < sarea_priv->nbox );
+       }
 
-               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);
-               }
+       if ( buf_priv->discard ) {
+               AGE_BUFFER( buf_priv );
+               buf->pending = 0;
+               buf->used = 0;
+               buf_priv->dispatched = 0;
 
-               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);
-               }
+               mga_freelist_put( dev, buf );
        }
 
-       /* Force reset of DWGCTL */
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]);
-       PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
-       PRIMADVANCE(dev_priv);
+       FLUSH_DMA();
 }
 
-static void mga_dma_dispatch_swap(drm_device_t * dev)
+/* 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;
-       int i;
-       int pixel_stride = dev_priv->stride / dev_priv->cpp;
+       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 );
 
-       PRIMLOCALS;
+       y2 = length / 64;
 
-       PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
+       BEGIN_DMA( 4 );
 
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
+       DMA_BLOCK( MGA_DSTORG,  dstorg,
+                  MGA_MACCESS, 0x00000000,
+                  MGA_SRCORG,  srcorg,
+                  MGA_AR5,     64 );
 
-       PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
-       PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
-       PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
-       PRIMOUTREG(MGAREG_AR5, pixel_stride);
+       DMA_BLOCK( MGA_PITCH,   64,
+                  MGA_PLNWT,   0xffffffff,
+                  MGA_DMAPAD,  0x00000000,
+                  MGA_DWGCTL,  MGA_DWGCTL_COPY );
 
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_PLNWT, ~0);
-       PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
+       DMA_BLOCK( MGA_AR0,     63,
+                  MGA_AR3,     0,
+                  MGA_FXBNDRY, (63 << 16) | 0,
+                  MGA_YDSTLEN + MGA_EXEC, y2 );
 
-       for (i = 0; i < nbox; i++) {
-               unsigned int h = pbox[i].y2 - pbox[i].y1;
-               unsigned int start = pbox[i].y1 * pixel_stride;
+       DMA_BLOCK( MGA_PLNWT,   ctx->plnwt,
+                  MGA_SRCORG,  dev_priv->front_offset,
+                  MGA_PITCH,   dev_priv->front_pitch,
+                  MGA_DWGSYNC, 0x00007000 );
 
-               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);
-       }
+       ADVANCE_DMA();
 
-       /* Force reset of DWGCTL */
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT]);
-       PRIMOUTREG(MGAREG_SRCORG, 0);
-       PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+       AGE_BUFFER( buf_priv );
+
+       buf->pending = 0;
+       buf->used = 0;
+       buf_priv->dispatched = 0;
 
-       PRIMADVANCE(dev_priv);
+       mga_freelist_put( dev, buf );
+
+       FLUSH_DMA();
 }
 
-/*  #define BLIT_LEFT  1 */
-/*  #define BLIT_UP            4 */
-
-static void mga_dma_dispatch_blit(drm_device_t * dev,
-                                 unsigned int planemask,
-                                 unsigned int source,
-                                 unsigned int dest,
-                                 int delta_sx, int delta_sy,
-                                 int delta_dx, int delta_dy,
-                                 int source_pitch,
-                                 int dest_pitch,
-                                 int height,
-                                 int ydir)
+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;
-       unsigned int *regs = sarea_priv->ContextState;
-       int nbox = sarea_priv->nbox;
+       drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
        drm_clip_rect_t *pbox = sarea_priv->boxes;
-       int pixel_stride = dev_priv->stride / dev_priv->cpp;
+       int nbox = sarea_priv->nbox;
        u32 scandir = 0, i;
-       
-       PRIMLOCALS;        
-
-       PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
-
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DMAPAD, 0);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7100);
-       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-
-       PRIMOUTREG(MGAREG_DWGCTL, MGA_COPY_CMD);
-       PRIMOUTREG(MGAREG_PLNWT, planemask);
-       PRIMOUTREG(MGAREG_SRCORG, source);
-       PRIMOUTREG(MGAREG_DSTORG, dest);
-
-       PRIMOUTREG(MGAREG_SGN, scandir);
-       PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
-       PRIMOUTREG(MGAREG_AR5, ydir * source_pitch);        
-       PRIMOUTREG(MGAREG_PITCH, dest_pitch);
-
-       for (i = 0; i < nbox; i++) {
-               int srcx = pbox[i].x1 + delta_sx;
-               int srcy = pbox[i].y1 + delta_sy;
-               int dstx = pbox[i].x1 + delta_dx;
-               int dsty = pbox[i].y1 + delta_dy;
+       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 (ydir == -1) {
-                       srcy = height - srcy - 1;
+               if ( blit->ydir == -1 ) {
+                       srcy = blit->height - srcy - 1;
                }
 
-               start = srcy * source_pitch + srcx;
+               start = srcy * blit->src_pitch + srcx;
 
-               PRIMOUTREG(MGAREG_AR0, start + w);
-               PRIMOUTREG(MGAREG_AR3, start);
-               PRIMOUTREG(MGAREG_FXBNDRY, ((dstx+w) << 16) | (dstx & 0xffff));
-               PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, (dsty << 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_PLNWT, regs[MGA_CTXREG_PLNWT]);
-       PRIMOUTREG(MGAREG_PITCH, pixel_stride);
-       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_blit(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_blit_t blit;
+       drm_mga_clear_t clear;
 
-       if (copy_from_user(&blit, (drm_mga_blit_t *) arg, sizeof(blit)))
-               return -EFAULT;
-               
-       DRM_DEBUG("%s\n", __FUNCTION__);
+       LOCK_TEST_WITH_RETURN( dev );
 
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_blit_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;
 
-       /* Make sure we restore the 3D state next time.
-        */
-       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
-       
-       if ((blit.source & 0x3) != (SO_srcmap_sys|SO_srcacc_pci) &&
-           (blit.dest & 0x3) != (SO_srcmap_sys|SO_srcacc_pci))
-       {
-          mga_dma_dispatch_blit(dev,
-                                blit.planemask, 
-                                blit.source,
-                                blit.dest,
-                                blit.delta_sx, blit.delta_sy,
-                                blit.delta_dx, blit.delta_dy,
-                                blit.source_pitch,
-                                blit.dest_pitch,
-                                blit.height,
-                                blit.ydir);
-       }
+       WRAP_TEST_WITH_RETURN( dev_priv );
 
+       mga_dma_dispatch_clear( dev, &clear );
 
-       PRIMUPDATE(dev_priv);
+       /* Make sure we restore the 3D state next time.
+        */
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 
-#ifdef __i386__
-       mga_flush_write_combine();
-#endif
-       mga_dma_schedule(dev, 1);
        return 0;
 }
 
-
-int mga_clear_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;
-       drm_mga_clear_t clear;
 
-       if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear)))
-               return -EFAULT;
-
-       if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
-               DRM_ERROR("mga_clear_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;
 
-       /* 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);
-       return 0;
-}
+       WRAP_TEST_WITH_RETURN( dev_priv );
 
-int mga_swap_bufs(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_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;
-       }
-
-       if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
-               sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
+       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;
 
-       buf = dma->buflist[iload.idx];
+       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;
 
-       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 ( mga_do_wait_for_idle( dev_priv ) < 0 )
+               return -EBUSY;
 
-       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 0
+       DRM_INFO( "   verifying iload...\n" );
+       if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) {
+               mga_freelist_put( dev, buf );
                return -EINVAL;
        }
+       DRM_INFO( "   verifying iload... done.\n" );
+#endif
 
-       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 );
 
-static int mga_dma_get_buffers(drm_device_t * dev, drm_dma_t * d)
-{
-       int i;
-       drm_buf_t *buf;
+       /* Make sure we restore the 3D state next time.
+        */
+       dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
 
-       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/linux/mga_ucode.h b/linux/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/linux/mga_warp.c b/linux/mga_warp.c
new file mode 100644 (file)
index 0000000..5994ab0
--- /dev/null
@@ -0,0 +1,215 @@
+/* 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_device_t *dev )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       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_device_t *dev )
+{
+       drm_mga_private_t *dev_priv = dev->dev_private;
+       u32 wmisc;
+       DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+       /* 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/linux/r128.h b/linux/r128.h
new file mode 100644 (file)
index 0000000..0440501
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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
+
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+
+#define __HAVE_MTRR            1
+
+#define __HAVE_CTX_BITMAP      1
+
+#define __HAVE_DMA             1
+
+#endif
index 279d640..05ae959 100644 (file)
  *
  * Authors:
  *   Gareth Hughes <gareth@valinux.com>
- *
  */
 
 #define __NO_VERSION__
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
 
@@ -149,7 +149,7 @@ static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
        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;
 
@@ -346,7 +346,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        drm_r128_private_t *dev_priv;
         int i;
 
-       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;
@@ -360,7 +360,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
         * the CCE ring code.
         */
        if ( dev_priv->is_pci ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -368,7 +368,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        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 );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -387,7 +387,7 @@ 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 );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -487,7 +487,7 @@ 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;
@@ -508,7 +508,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
        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;
@@ -517,8 +517,8 @@ static int r128_do_cleanup_cce( drm_device_t *dev )
                DRM_IOREMAPFREE( dev_priv->ring_rptr );
                DRM_IOREMAPFREE( dev_priv->buffers );
 
-               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;
        }
 
@@ -740,8 +740,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;
 
@@ -752,8 +752,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;
diff --git a/linux/r128_context.c b/linux/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 3454de7..aaf2ce3 100644 (file)
@@ -142,12 +142,6 @@ typedef struct {
 } 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.
index cd5c0e8..08de203 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"
 
-#define R128_NAME              "r128"
-#define R128_DESC              "ATI Rage 128"
-#define R128_DATE              "20010130"
-#define R128_MAJOR             2
-#define R128_MINOR             1
-#define R128_PATCHLEVEL                4
-
-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 },
-#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_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_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");
-
-#ifndef MODULE
-/* r128_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)
-{
-       drm_parse_options(str);
-       return 1;
-}
-
-__setup("r128=", 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);
-
-       /* Force the cleanup of page flipping when required */
-       if ( dev->dev_private ) {
-               drm_r128_private_t *dev_priv = dev->dev_private;
-               if ( dev_priv->page_flipping ) {
-                       r128_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 r128_takedown(dev);
-               }
-               spin_unlock(&dev->count_lock);
-       }
-
-       unlock_kernel();
-       return retcode;
-}
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "r128"
+#define DRIVER_DESC            "ATI Rage 128"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           2
+#define DRIVER_MINOR           1
+#define DRIVER_PATCHLEVEL      4
+
+#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 },
 
-/* 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);
-               }
-       }
-
-       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;
-}
+/* 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
+
+#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)
+
+#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)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_r128_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_r128_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 0b2e925..950a471 100644 (file)
@@ -109,18 +109,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 );
@@ -146,6 +134,7 @@ 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 );
 
 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 */
@@ -166,31 +155,6 @@ extern int r128_cce_stipple( struct inode *inode, struct file *filp,
 extern int r128_cce_indirect( 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);
-
 
 /* Register definitions, register access macros and drmAddMap constants
  * for Rage 128 kernel driver.
@@ -404,15 +368,15 @@ extern int  r128_context_switch_complete(drm_device_t *dev, int new);
 
 
 #define R128_BASE(reg)         ((u32)(dev_priv->mmio->handle))
-#define R128_ADDR(reg)         (R128_BASE(reg) + reg)
+#define R128_ADDR(reg)         (R128_BASE( reg ) + reg)
 
-#define R128_DEREF(reg)                *(volatile u32 *)R128_ADDR(reg)
-#define R128_READ(reg)         R128_DEREF(reg)
-#define R128_WRITE(reg,val)    do { R128_DEREF(reg) = val; } while (0)
+#define R128_DEREF(reg)                *(volatile u32 *)R128_ADDR( reg )
+#define R128_READ(reg)         R128_DEREF( reg )
+#define R128_WRITE(reg,val)    do { R128_DEREF( reg ) = val; } while (0)
 
-#define R128_DEREF8(reg)       *(volatile u8 *)R128_ADDR(reg)
-#define R128_READ8(reg)                R128_DEREF8(reg)
-#define R128_WRITE8(reg,val)   do { R128_DEREF8(reg) = val; } while (0)
+#define R128_DEREF8(reg)       *(volatile u8 *)R128_ADDR( reg )
+#define R128_READ8(reg)                R128_DEREF8( reg )
+#define R128_WRITE8(reg,val)   do { R128_DEREF8( reg ) = val; } while (0)
 
 
 #define R128_WRITE_PLL(addr,val)                                              \
index badf87e..a4683c4 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #define __NO_VERSION__
+#include "r128.h"
 #include "drmP.h"
 #include "r128_drv.h"
 #include "drm.h"
diff --git a/linux/radeon.h b/linux/radeon.h
new file mode 100644 (file)
index 0000000..6ef9927
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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
+
+#define __HAVE_AGP             1
+#define __MUST_HAVE_AGP                1
+
+#define __HAVE_MTRR            1
+
+#define __HAVE_CTX_BITMAP      1
+
+#define __HAVE_DMA             1
+
+#endif
diff --git a/linux/radeon_bufs.c b/linux/radeon_bufs.c
deleted file mode 100644 (file)
index 9a3093e..0000000
+++ /dev/null
@@ -1,298 +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 */
-       }
-
-       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);
-               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(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, map->size,
-                                         PROT_READ|PROT_WRITE,
-                                         MAP_SHARED,
-                                         (unsigned long)map->offset);
-                       up(&current->mm->mmap_sem);
-               } else {
-                       down(&current->mm->mmap_sem);
-                       virtual = do_mmap(filp, 0, dma->byte_count,
-                                         PROT_READ|PROT_WRITE, MAP_SHARED, 0);
-                       up(&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/linux/radeon_context.c b/linux/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 f96d469..75b24ee 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define __NO_VERSION__
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
 
@@ -603,7 +604,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
        drm_radeon_private_t *dev_priv;
         int i;
 
-       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;
@@ -617,7 +618,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
         * the CP ring code.
         */
        if ( dev_priv->is_pci ) {
-               drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -625,7 +626,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
        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 );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -642,7 +643,7 @@ 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 );
+               DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
                dev->dev_private = NULL;
                return -EINVAL;
        }
@@ -752,7 +753,7 @@ 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;
@@ -798,7 +799,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
        return 0;
 }
 
-static int radeon_do_cleanup_cp( drm_device_t *dev )
+int radeon_do_cleanup_cp( drm_device_t *dev )
 {
        if ( dev->dev_private ) {
                drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -807,8 +808,8 @@ static int radeon_do_cleanup_cp( drm_device_t *dev )
                DRM_IOREMAPFREE( dev_priv->ring_rptr );
                DRM_IOREMAPFREE( dev_priv->buffers );
 
-               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;
        }
 
@@ -1055,8 +1056,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;
 
@@ -1067,8 +1068,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;
index 0113ed9..da04610 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"
 
-#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 },
-#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");
-
-#ifndef MODULE
-/* radeon_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)
-{
-       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. */
+#define DRIVER_AUTHOR          "Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME            "radeon"
+#define DRIVER_DESC            "ATI Radeon"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#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_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 },
 
-       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);
-#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;
-}
+/* 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
+
+#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)
+
+#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)
+
+#include "drm_drv.h"
+
+
+#define DRIVER_BUF_PRIV_T      drm_radeon_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )                                  \
+       ((drm_radeon_private_t *)((dev)->dev_private))->buffers
+
+#include "drm_bufs.h"
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#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 e2c3ebd..656d6e0 100644 (file)
@@ -126,18 +126,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 );
@@ -163,6 +151,7 @@ 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 );
 
 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 */
@@ -181,31 +170,6 @@ extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
 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.
index 13da7d0..9b84a73 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #define __NO_VERSION__
+#include "radeon.h"
 #include "drmP.h"
 #include "radeon_drv.h"
 #include "drm.h"
diff --git a/linux/tdfx.h b/linux/tdfx.h
new file mode 100644 (file)
index 0000000..6af675f
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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
+
+#define __HAVE_MTRR            1
+#define __HAVE_CTX_BITMAP      1
+
+#endif
diff --git a/linux/tdfx_context.c b/linux/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 b98a298..9bb7b84 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       "20001030"
-#define TDFX_MAJOR      1
-#define TDFX_MINOR      0
-#define TDFX_PATCHLEVEL  0
-
-static drm_device_t          tdfx_device;
-drm_ctx_t                    tdfx_res_ctx;
-
-static struct file_operations tdfx_fops = {
-#if LINUX_VERSION_CODE >= 0x020400
-                               /* This started being used during 2.4.0-test */
-       owner:   THIS_MODULE,
-#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_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 },
-
-       [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");
-
-#ifndef MODULE
-/* tdfx_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)
-{
-       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;
-       }
-#endif
 
-       unblock_all_signals();
-       return 0;
-}
+#define DRIVER_AUTHOR          "VA Linux Systems Inc."
+
+#define DRIVER_NAME            "tdfx"
+#define DRIVER_DESC            "3dfx Banshee/Voodoo3+"
+#define DRIVER_DATE            "20010214"
+
+#define DRIVER_MAJOR           1
+#define DRIVER_MINOR           0
+#define DRIVER_PATCHLEVEL      0
+
+#include "drm_drv.h"
+
+
+#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_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/linux/tdfx_drv.h b/linux/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
index dc3d262..470eb03 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,6 +35,7 @@
 #ifndef _DRM_H_
 #define _DRM_H_
 
+#include <linux/config.h>
 #if defined(__linux__)
 #include <asm/ioctl.h>         /* For _IO* macros */
 #define DRM_IOCTL_NR(n)             _IOC_NR(n)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC   "/proc/misc"
-#define DRM_PROC_DRM    "/proc/drm"
-#define DRM_DEV_DRM     "/dev/drm"
 #define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID     0
 #define DRM_DEV_GID     0
 
-
+#define DRM_MAJOR       226
 #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                 */
@@ -72,12 +69,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"
@@ -150,6 +155,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        */
@@ -309,6 +352,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)
@@ -345,17 +391,18 @@ 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 */
+/* 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)
index dc3d262..470eb03 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,6 +35,7 @@
 #ifndef _DRM_H_
 #define _DRM_H_
 
+#include <linux/config.h>
 #if defined(__linux__)
 #include <asm/ioctl.h>         /* For _IO* macros */
 #define DRM_IOCTL_NR(n)             _IOC_NR(n)
 #define DRM_IOCTL_NR(n)             ((n) & 0xff)
 #endif
 
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC   "/proc/misc"
-#define DRM_PROC_DRM    "/proc/drm"
-#define DRM_DEV_DRM     "/dev/drm"
 #define DRM_DEV_MODE    (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
 #define DRM_DEV_UID     0
 #define DRM_DEV_GID     0
 
-
+#define DRM_MAJOR       226
 #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                 */
@@ -72,12 +69,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"
@@ -150,6 +155,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        */
@@ -309,6 +352,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)
@@ -345,17 +391,18 @@ 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 */
+/* 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)
diff --git a/tests/dristat.c b/tests/dristat.c
new file mode 100644 (file)
index 0000000..f429efd
--- /dev/null
@@ -0,0 +1,473 @@
+/* dristat.c -- 
+ * Created: Mon Jan 15 05:05:07 2001 by faith@acm.org
+ *
+ * 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: Rickard E. (Rik) Faith <faith@valinux.com>
+ * 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "../../../xf86drm.h"
+#include "../xf86drmRandom.c"
+#include "../xf86drmHash.c"
+#include "../xf86drm.c"
+
+#define DRM_DIR_NAME "/dev/dri"
+#define DRM_DEV_NAME "%s/card%d"
+
+#define DRM_VERSION 0x00000001
+#define DRM_MEMORY  0x00000002
+#define DRM_CLIENTS 0x00000004
+#define DRM_STATS   0x00000008
+
+typedef struct drmStatsS {
+    unsigned long count;
+    struct {
+       unsigned long value;
+       const char    *long_format;
+       const char    *long_name;
+       const char    *rate_format;
+       const char    *rate_name;
+       int           isvalue;
+       const char    *mult_names;
+       int           mult;
+       int           verbose;
+    } data[15];
+} drmStatsT;
+
+static void getversion(int fd)
+{
+    drmVersionPtr version;
+    
+    version = drmGetVersion(fd);
+    if (version) {
+       printf("  Version information:\n");
+       printf("    Name: %s\n", version->name ? version->name : "?");
+       printf("    Version: %d.%d.%d\n",
+              version->version_major,
+              version->version_minor,
+              version->version_patchlevel);
+       printf("    Date: %s\n", version->date ? version->date : "?");
+       printf("    Desc: %s\n", version->desc ? version->desc : "?");
+       drmFreeVersion(version);
+    } else {
+       printf("  No version information available\n");
+    }
+}
+
+typedef struct {
+    unsigned long      offset;  /* Requested physical address (0 for SAREA)*/
+    unsigned long      size;    /* Requested physical size (bytes)         */
+    drm_map_type_t     type;    /* Type of memory to map                   */
+    drm_map_flags_t flags;      /* Flags                                   */
+    void               *handle; /* User-space: "Handle" to pass to mmap    */
+    /* Kernel-space: kernel-virtual address    */
+    int                mtrr;    /* MTRR slot used                          */
+                                /* Private data                            */
+} drmVmRec, *drmVmPtr;
+
+int drmGetMap(int fd, int idx, drmHandle *offset, drmSize *size,
+             drmMapType *type, drmMapFlags *flags, drmHandle *handle,
+             int *mtrr)
+{
+    drm_map_t map;
+
+    map.offset = idx;
+    if (ioctl(fd, DRM_IOCTL_GET_MAP, &map)) return -errno;
+    *offset = map.offset;
+    *size   = map.size;
+    *type   = map.type;
+    *flags  = map.flags;
+    *handle = (unsigned long)map.handle;
+    *mtrr   = map.mtrr;
+    return 0;
+}
+
+int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
+                unsigned long *magic, unsigned long *iocs)
+{
+    drm_client_t client;
+
+    client.idx = idx;
+    if (ioctl(fd, DRM_IOCTL_GET_CLIENT, &client)) return -errno;
+    *auth      = client.auth;
+    *pid       = client.pid;
+    *uid       = client.uid;
+    *magic     = client.magic;
+    *iocs      = client.iocs;
+    return 0;
+}
+
+int drmGetStats(int fd, drmStatsT *stats)
+{
+    drm_stats_t s;
+    int         i;
+
+    if (ioctl(fd, DRM_IOCTL_GET_STATS, &s)) return -errno;
+
+    stats->count = 0;
+    memset(stats, 0, sizeof(*stats));
+    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
+       return -1;
+
+#define SET_VALUE                              \
+    stats->data[i].long_format = "%-20.20s";   \
+    stats->data[i].rate_format = "%8.8s";      \
+    stats->data[i].isvalue     = 1;            \
+    stats->data[i].verbose     = 0
+
+#define SET_COUNT                              \
+    stats->data[i].long_format = "%-20.20s";     \
+    stats->data[i].rate_format = "%5.5s";      \
+    stats->data[i].isvalue     = 0;            \
+    stats->data[i].mult_names  = "kgm";        \
+    stats->data[i].mult        = 1000;         \
+    stats->data[i].verbose     = 0
+
+#define SET_BYTE                             \
+    stats->data[i].long_format = "%-9.9s";   \
+    stats->data[i].rate_format = "%5.5s";    \
+    stats->data[i].isvalue     = 0;          \
+    stats->data[i].mult_names  = "KGM";      \
+    stats->data[i].mult        = 1024;       \
+    stats->data[i].verbose     = 0
+
+
+    stats->count = s.count;
+    for (i = 0; i < s.count; i++) {
+       stats->data[i].value = s.data[i].value;
+       switch (s.data[i].type) {
+       case _DRM_STAT_LOCK:
+           stats->data[i].long_name = "Lock";
+           stats->data[i].rate_name = "Lock";
+           SET_VALUE;
+           break;
+       case _DRM_STAT_OPENS:
+           stats->data[i].long_name = "Opens";
+           stats->data[i].rate_name = "O";
+           SET_COUNT;
+           stats->data[i].verbose   = 1;
+           break;
+       case _DRM_STAT_CLOSES:
+           stats->data[i].long_name = "Closes";
+           stats->data[i].rate_name = "Lock";
+           SET_COUNT;
+           stats->data[i].verbose   = 1;
+           break;
+       case _DRM_STAT_IOCTLS:
+           stats->data[i].long_name = "Ioctls";
+           stats->data[i].rate_name = "Ioc/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_LOCKS:
+           stats->data[i].long_name = "Locks";
+           stats->data[i].rate_name = "Lck/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_UNLOCKS:
+           stats->data[i].long_name = "Unlocks";
+           stats->data[i].rate_name = "Unl/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_IRQ:
+           stats->data[i].long_name = "IRQs";
+           stats->data[i].rate_name = "IRQ/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_PRIMARY:
+           stats->data[i].long_name = "Primary Bytes";
+           stats->data[i].rate_name = "PB/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_SECONDARY:
+           stats->data[i].long_name = "Secondary Bytes";
+           stats->data[i].rate_name = "SB/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_DMA:
+           stats->data[i].long_name = "DMA";
+           stats->data[i].rate_name = "DMA/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_SPECIAL:
+           stats->data[i].long_name = "Special DMA";
+           stats->data[i].rate_name = "dma/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_MISSED:
+           stats->data[i].long_name = "Miss";
+           stats->data[i].rate_name = "Ms/s";
+           SET_COUNT;
+           break;
+       case _DRM_STAT_VALUE:
+           stats->data[i].long_name = "Value";
+           stats->data[i].rate_name = "Value";
+           SET_VALUE;
+           break;
+       case _DRM_STAT_BYTE:
+           stats->data[i].long_name = "Bytes";
+           stats->data[i].rate_name = "B/s";
+           SET_BYTE;
+           break;
+       case _DRM_STAT_COUNT:
+       default:
+           stats->data[i].long_name = "Count";
+           stats->data[i].rate_name = "Cnt/s";
+           SET_COUNT;
+           break;
+       }
+    }
+    return 0;
+}
+
+static void getvm(int fd)
+{
+    int             i;
+    const char      *typename;
+    char            flagname[33];
+    drmHandle       offset;
+    drmSize         size;
+    drmMapType      type;
+    drmMapFlags     flags;
+    drmHandle       handle;
+    int             mtrr;
+
+    printf("  VM map information:\n");
+    printf("    slot     offset       size type flags    address mtrr\n");
+
+    for (i = 0;
+        !drmGetMap(fd, i, &offset, &size, &type, &flags, &handle, &mtrr);
+        i++) {
+       
+       switch (type) {
+       case DRM_FRAME_BUFFER: typename = "FB";  break;
+       case DRM_REGISTERS:    typename = "REG"; break;
+       case DRM_SHM:          typename = "SHM"; break;
+       case DRM_AGP:          typename = "AGP"; break;
+       default:               typename = "???"; break;
+       }
+
+       flagname[0] = (flags & DRM_RESTRICTED)      ? 'R' : ' ';
+       flagname[1] = (flags & DRM_READ_ONLY)       ? 'r' : 'w';
+       flagname[2] = (flags & DRM_LOCKED)          ? 'l' : ' ';
+       flagname[3] = (flags & DRM_KERNEL)          ? 'k' : ' ';
+       flagname[4] = (flags & DRM_WRITE_COMBINING) ? 'W' : ' ';
+       flagname[5] = (flags & DRM_CONTAINS_LOCK)   ? 'L' : ' ';
+       flagname[6] = '\0';
+       
+       printf("    %4d 0x%08lx 0x%08lx %3.3s %6.6s 0x%08lx ",
+              i, offset, (unsigned long)size, typename, flagname, handle);
+       if (mtrr < 0) printf("none\n");
+       else          printf("%4d\n", mtrr);
+    }
+}
+
+static void getclients(int fd)
+{
+    int           i;
+    int           auth;
+    int           pid;
+    int           uid;
+    unsigned long magic;
+    unsigned long iocs;
+    char          buf[64];
+    char          cmd[40];
+    int           procfd;
+    
+    printf("  DRI client information:\n");
+    printf("    a   pid    uid      magic     ioctls  prog\n");
+
+    for (i = 0; !drmGetClient(fd, i, &auth, &pid, &uid, &magic, &iocs); i++) {
+       sprintf(buf, "/proc/%d/cmdline", pid);
+       memset(cmd, sizeof(cmd), 0);
+       if ((procfd = open(buf, O_RDONLY, 0)) >= 0) {
+           read(procfd, cmd, sizeof(cmd)-1);
+           close(procfd);
+       }
+       if (*cmd)
+           printf("    %c %5d %5d %10lu %10lu   %s\n",
+                  auth ? 'y' : 'n', pid, uid, magic, iocs, cmd);
+       else
+           printf("    %c %5d %5d %10lu %10lu\n",
+                  auth ? 'y' : 'n', pid, uid, magic, iocs);
+    }
+}
+
+static void printhuman(unsigned long value, const char *name, int mult)
+{
+    const char *p;
+    double     f;
+                               /* Print width 5 number in width 6 space */
+    if (value < 100000) {
+       printf(" %5lu", value);
+       return;
+    }
+
+    p = name;
+    f = (double)value / (double)mult;
+    if (f < 10.0) {
+       printf(" %4.2f%c", f, *p);
+       return;
+    }
+
+    p++;
+    f = (double)value / (double)mult;
+    if (f < 10.0) {
+       printf(" %4.2f%c", f, *p);
+       return;
+    }
+    
+    p++;
+    f = (double)value / (double)mult;
+    if (f < 10.0) {
+       printf(" %4.2f%c", f, *p);
+       return;
+    }
+}
+
+static void getstats(int fd, int i)
+{
+    drmStatsT prev, curr;
+    int       j;
+    double    rate;
+    
+    printf("  System statistics:\n");
+
+    if (drmGetStats(fd, &prev)) return;
+    if (!i) {
+       for (j = 0; j < prev.count; j++) {
+           printf("    ");
+           printf(prev.data[j].long_format, prev.data[j].long_name);
+           if (prev.data[j].isvalue) printf(" 0x%08lx\n", prev.data[j].value);
+           else                      printf(" %10lu\n", prev.data[j].value);
+       }
+       return;
+    }
+
+    printf("    ");
+    for (j = 0; j < prev.count; j++)
+       if (!prev.data[j].verbose) {
+           printf(" ");
+           printf(prev.data[j].rate_format, prev.data[j].rate_name);
+       }
+    printf("\n");
+    
+    for (;;) {
+       sleep(i);
+       if (drmGetStats(fd, &curr)) return;
+       printf("    ");
+       for (j = 0; j < curr.count; j++) {
+           if (curr.data[j].verbose) continue;
+           if (curr.data[j].isvalue) {
+               printf(" %08lx", curr.data[j].value);
+           } else {
+               rate = (curr.data[j].value - prev.data[j].value) / (double)i;
+               printhuman(rate, curr.data[j].mult_names, curr.data[j].mult);
+           }
+       }
+       printf("\n");
+       memcpy(&prev, &curr, sizeof(prev));
+    }
+    
+}
+
+static int drmOpenMinor(int minor, uid_t user, gid_t group,
+                       mode_t dirmode, mode_t devmode, int force)
+{
+    struct stat st;
+    char        buf[64];
+    long        dev    = makedev(DRM_MAJOR, minor);
+    int         setdir = 0;
+    int         setdev = 0;
+    int         fd;
+
+    if (stat(DRM_DIR_NAME, &st) || !S_ISDIR(st.st_mode)) {
+       remove(DRM_DIR_NAME);
+       mkdir(DRM_DIR_NAME, dirmode);
+       ++setdir;
+    }
+
+    if (force || setdir) {
+       chown(DRM_DIR_NAME, user, group);
+       chmod(DRM_DIR_NAME, dirmode);
+    }
+
+    sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+    if (stat(buf, &st) || st.st_rdev != dev) {
+       remove(buf);
+       mknod(buf, S_IFCHR, dev);
+       ++setdev;
+    }
+
+    if (force || setdev) {
+       chown(buf, user, group);
+       chmod(buf, devmode);
+    }
+
+    if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd;
+    if (setdev) remove(buf);
+    return -errno;
+}
+       
+int main(int argc, char **argv)
+{
+    int  c;
+    int  mask     = 0;
+    int  minor    = 0;
+    int  interval = 0;
+    int  fd;
+    char buf[64];
+    int  i;
+
+    while ((c = getopt(argc, argv, "avmcsM:i:")) != EOF)
+       switch (c) {
+       case 'a': mask = ~0;                          break;
+       case 'v': mask |= DRM_VERSION;                break;
+       case 'm': mask |= DRM_MEMORY;                 break;
+       case 'c': mask |= DRM_CLIENTS;                break;
+       case 's': mask |= DRM_STATS;                  break;
+       case 'i': interval = strtol(optarg, NULL, 0); break;
+       case 'M': minor = strtol(optarg, NULL, 0);    break;
+       default:
+           fprintf( stderr, "Usage: dristat [options]\n" );
+           return 1;
+       }
+
+    for (i = 0; i < 16; i++) if (!minor || i == minor) {
+       sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
+       fd = drmOpenMinor(i, 0, 0, 0700, 0600, 0);
+       if (fd >= 0) {
+           printf("%s\n", buf);
+           if (mask & DRM_VERSION) getversion(fd);
+           if (mask & DRM_MEMORY)  getvm(fd);
+           if (mask & DRM_CLIENTS) getclients(fd);
+           if (mask & DRM_STATS)   getstats(fd, interval);
+           close(fd);
+       }
+    }
+
+    return 0; 
+}