]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.31 2.3.31
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:06 +0000 (15:29 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:29:06 +0000 (15:29 -0500)
60 files changed:
Documentation/Configure.help
MAINTAINERS
Makefile
arch/alpha/config.in
arch/alpha/defconfig
arch/alpha/kernel/irq.c
arch/arm/config.in
arch/arm/defconfig
arch/i386/config.in
arch/i386/defconfig
arch/i386/kernel/entry.S
arch/i386/kernel/setup.c
arch/i386/mm/ioremap.c
arch/m68k/config.in
arch/mips/config.in
arch/mips/defconfig
arch/ppc/config.in
arch/ppc/defconfig
arch/sparc/config.in
arch/sparc/defconfig
arch/sparc64/config.in
arch/sparc64/defconfig
drivers/char/Config.in
drivers/char/Makefile
drivers/char/agp/Makefile [new file with mode: 0644]
drivers/char/agp/agp_backend.c [new file with mode: 0644]
drivers/char/agp/agp_backendP.h [new file with mode: 0644]
drivers/char/agp/agpgart_fe.c [new file with mode: 0644]
drivers/char/drm/bufs.c
drivers/char/drm/drmP.h
drivers/char/drm/gamma_drv.c
drivers/char/drm/tdfx_drv.c
drivers/net/Config.in
drivers/net/aironet4500.h
drivers/net/aironet4500_card.c
drivers/net/aironet4500_core.c
drivers/net/aironet4500_proc.c
drivers/net/aironet4500_rid.c
drivers/net/lance.c
drivers/net/pcmcia/aironet4500_cs.c
drivers/pci/Config.in [new file with mode: 0644]
drivers/pci/Makefile
drivers/pci/gen-devlist.c
drivers/pci/names.c
drivers/pci/pci.c
drivers/pci/pci.ids
drivers/pci/proc.c
drivers/scsi/aic7xxx.c
drivers/scsi/sgiwd93.c
drivers/usb/Config.in
drivers/usb/Makefile
drivers/usb/hub.c
drivers/usb/usb-core.c
fs/open.c
include/asm-i386/unistd.h
include/linux/agp_backend.h [new file with mode: 0644]
include/linux/agpgart.h [new file with mode: 0644]
include/linux/pci.h
include/linux/pci_ids.h
kernel/capability.c

index 1d098d27bc7d4cbdf10c5b78859fdb33c65d1b3a..fad694c0c80ca0edf61495d090a8b65d2fadc3f5 100644 (file)
@@ -1720,6 +1720,19 @@ CONFIG_PCI_GOBIOS
   kernel will try the direct access method and falls back to the BIOS
   if that doesn't work. If unsure, go with the default.
 
+PCI device name database
+CONFIG_PCI_NAMES
+  By default, the kernel contains a database of all known PCI device
+  names to make the information in /proc/pci, /proc/ioports and similar
+  files comprehensible to the user. This database increases size of
+  the kernel image by about 80KB, but it gets freed after the system
+  boots up, so it doesn't take up kernel memory. Anyway, if you are
+  building an installation floppy or kernel for an embedded system
+  where kernel image size really matters, you can disable this feature
+  and you'll get device ID numbers instead of names.
+
+  When in doubt, say Y.
+
 MCA support
 CONFIG_MCA
   MicroChannel Architecture is found in some IBM PS/2 machines and
@@ -5554,13 +5567,13 @@ CONFIG_AIRONET4500_PCI
        This option should be enabled for PCI cards
        module aironet4500_card
 
-Aironet 4500/4800 ISA broken support
+Aironet 4500/4800 ISA broken support (EXPERIMENTAL)
 CONFIG_AIRONET4500_ISA
        This option enables support for ISA cards in non-PNP mode. 
        Does not operate correctly by now.
        module aironet4500_card
 
-Aironet 4500/4800 I365 broken support
+Aironet 4500/4800 I365 broken support (EXPERIMENTAL)
 CONFIG_AIRONET4500_I365
        This option enables support for PCMCIA cards on i365 controller 
        _without_ cardservices. Doesnt have much sense and is not working
index 2c9c9f8ef9b9d894a770310ed0df3070d3e616e6..d9eac38d8636f3982335a8cd8f6a955c8822f440 100644 (file)
@@ -928,6 +928,13 @@ L: linux-kernel@vger.rutgers.edu
 W:     http://www.kernel.dk
 S:     Maintained
 
+USB SUBSYSTEM
+P:     Randy Dunlap
+M:     randy.dunlap@intel.com
+L:     linux-usb@suse.com
+W:     http://www.linux-usb.org
+S:     Supported
+
 USB HUB AND UHCI DRIVERS
 P:     Johannes Erdfelt
 M:     jerdfelt@sventech.com
index 4e32f9747ea8479848ab4f63bb25023e229e3d6d..15c712d6daeea13958dbbc832d46d838e7c1f5a9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -400,7 +400,7 @@ clean:      archclean
        rm -f .tmp*
        rm -f drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c
        rm -f drivers/char/conmakehash
-       rm -f drivers/pci/devlist.h drivers/pci/gen-devlist
+       rm -f drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist
        rm -f drivers/sound/bin2hex drivers/sound/hex2hex
        rm -f net/khttpd/make_times_h
        rm -f net/khttpd/times.h
index f52aeb4fad5b5e1574d2aeebda05ae0830953218..35e9edeb0479c48cb2ba58a8fcbff5da5007c3ea 100644 (file)
@@ -178,6 +178,8 @@ then
        bool 'Symmetric multi-processing support' CONFIG_SMP
 fi
 
+source drivers/pci/Config.in
+
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
index a2bba43ffd5c023baac8157621ca5e20833d0a43..ba6f0070b922b8c25579f1cbf6577d889e8a5d40 100644 (file)
@@ -44,6 +44,7 @@ CONFIG_ALPHA_GENERIC=y
 # CONFIG_ALPHA_SABLE is not set
 # CONFIG_ALPHA_TAKARA is not set
 CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
 # CONFIG_SMP is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
index 8368be9b26677dcdae3e2cd986a6e6c3043ee7b1..d6d6e061180ec83e873f22fb4b291c61ba870c9d 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 #include <asm/machvec.h>
-#include <asm/spinlock.h>
 
 #include "proto.h"
 
index 249759e1ad6946ce50012f9a3dca464a01dea858..e1d54c4e7f0ec5831fcbcaa68a05353578c969f1 100644 (file)
@@ -110,6 +110,7 @@ fi
 if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
      "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
    define_bool CONFIG_PCI y
+   source drivers/pci/Config.h
 fi
 
 #
index 1c39a89badeb2c0f6cf744fe898f62a1e9bed2b7..2aba351c25dc4f98f304f12b5855aa4c99c74903 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_ARCH_EBSA285=y
 CONFIG_ARCH_NETWINDER=y
 # CONFIG_ARCH_ACORN is not set
 CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
 CONFIG_ISA_DMA=y
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
index 03433d968f4be43aba4997659aca01a09463b5fe..4a09997b2c74cc46770e55c5a66fe684665d2897 100644 (file)
@@ -95,8 +95,12 @@ else
          define_bool CONFIG_PCI_DIRECT y
       fi
    fi
-   bool 'MCA support' CONFIG_MCA
+fi
 
+source drivers/pci/Config.in
+
+if [ "$CONFIG_VISWS" != "y" ]; then
+   bool 'MCA support' CONFIG_MCA
 fi
 
 source drivers/pcmcia/Config.in
index bd9cc96b6bc42d290412b5569787b83330eda7cb..d7e19c7834be63a674b8d37cea338961e3b323c4 100644 (file)
@@ -51,6 +51,7 @@ CONFIG_PCI=y
 CONFIG_PCI_GOANY=y
 CONFIG_PCI_BIOS=y
 CONFIG_PCI_DIRECT=y
+CONFIG_PCI_NAMES=y
 # CONFIG_MCA is not set
 
 #
index 0f8534b7e2c354eaa7ddd2b44388a66395eb2ca0..4eef2d8c9e14eee5b858a7798722677fd6aa2bdd 100644 (file)
@@ -593,6 +593,9 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_vfork)            /* 190 */
        .long SYMBOL_NAME(sys_getrlimit)
        .long SYMBOL_NAME(sys_mmap2)
+       .long SYMBOL_NAME(sys_truncate64)
+       .long SYMBOL_NAME(sys_ftruncate64)
+       /* 195 */
 
        /*
         * NOTE!! This doesn't have to be exact - we just have
@@ -600,6 +603,6 @@ ENTRY(sys_call_table)
         * entries. Don't panic if you notice that this hasn't
         * been shrunk every time we add a new system call.
         */
-       .rept NR_syscalls-192
+       .rept NR_syscalls-194
                .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index a3d158dc16890755e2b7b81bb502b3a6d3d22e6c..646532f86a00f06eb97b7ac3f6b1c7e89e94cfe3 100644 (file)
@@ -1371,9 +1371,9 @@ int get_cpuinfo(char * buffer)
        char *p = buffer;
        int sep_bug;
        static char *x86_cap_flags[] = {
-               "fpu", "vme", "de", "pse", "tsc", "msr", "6", "mce",
-               "cx8", "9", "10", "sep", "mtrr", "pge", "14", "cmov",
-               "16", "17", "psn", "19", "20", "21", "22", "mmx",
+               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+               "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
+               "pat", "17", "psn", "19", "20", "21", "22", "mmx",
                "24", "kni", "26", "27", "28", "29", "30", "31"
        };
        struct cpuinfo_x86 *c = cpu_data;
@@ -1419,15 +1419,14 @@ int get_cpuinfo(char * buffer)
                    case X86_VENDOR_AMD:
                        if (c->x86 == 5 && c->x86_model == 6)
                                x86_cap_flags[10] = "sep";
-                       x86_cap_flags[16] = "fcmov";
+                       if (c->x86 < 6)
+                               x86_cap_flags[16] = "fcmov";
+                       x86_cap_flags[22] = "mmxext";
+                       x86_cap_flags[30] = "3dnowext";
                        x86_cap_flags[31] = "3dnow";
                        break;
 
                    case X86_VENDOR_INTEL:
-                       x86_cap_flags[6] = "pae";
-                       x86_cap_flags[9] = "apic";
-                       x86_cap_flags[14] = "mca";
-                       x86_cap_flags[16] = "pat";
                        x86_cap_flags[17] = "pse36";
                        x86_cap_flags[18] = "psn";
                        x86_cap_flags[24] = "osfxsr";
index 431adb3c6ee1a541a982452d9d7429929b79c760..cb44276729cded976f4112d45e9efe6d43e0f229 100644 (file)
@@ -119,8 +119,18 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
        /*
         * Don't allow anybody to remap normal RAM that we're using..
         */
-       if (phys_addr < virt_to_phys(high_memory))
-               return NULL;
+       if (phys_addr < virt_to_phys(high_memory)) {
+               char *t_addr, *t_end;
+               int i;
+
+               t_addr = __va(phys_addr);
+               t_end = t_addr + (size - 1);
+          
+               for(i = MAP_NR(t_addr); i < MAP_NR(t_end); i++) {
+                       if(!PageReserved(mem_map + i))
+                               return NULL;
+               }
+       }
 
        /*
         * Mappings have to be page-aligned
index 4888b4b48af20a9be3c1b374934196a7336bc685..2d60956943270fb228b083bb019a0b3aa60eb436 100644 (file)
@@ -124,6 +124,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    fi
 fi
 
+source drivers/pci/Config.in
 
 endmenu
 
index b856a2ac08d268ec4a97c27461ea7cda5364f0cd..d3b462e6e4ddc3302b6dfc9a21031bc6eab9d572 100644 (file)
@@ -100,6 +100,8 @@ if [ "$CONFIG_MODULES" = "y" ]; then
    bool '  Kernel module loader' CONFIG_KMOD
 fi
 
+source drivers/pci/Config.in
+
 endmenu
 
 if [ "$CONFIG_DECSTATION" = "y" ]; then
index 8f00bc8120470d7513d9ffd60d6f8fb49d787538..583ffbf768aea821666c4c9cd6231d32d42c89e0 100644 (file)
@@ -16,6 +16,7 @@
 # CONFIG_SGI is not set
 CONFIG_SNI_RM200_PCI=y
 CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
 
 #
 # CPU selection
index e989838e328eaa401280566038eff5975b3114cf..279d81438551d56cdecd358aff21943bd411554b 100644 (file)
@@ -106,6 +106,8 @@ define_bool CONFIG_BINFMT_ELF y
 define_bool CONFIG_KERNEL_ELF y
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
+source drivers/pci/Config.in
+
 source drivers/pcmcia/Config.in
 
 source drivers/parport/Config.in
index 19404751d5f3a99e1376e364c6e9a1648da4a666..671fc7637a7e6cbd6f8d0fa05d519df079fdf108 100644 (file)
@@ -35,8 +35,8 @@ CONFIG_KMOD=y
 #
 # General setup
 #
-# CONFIG_PCI is not set
 CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
 CONFIG_NET=y
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
index 81fc41f5d8fe8e526e935d80257e5c5c473309d0..27a756a2a2be6bcde2c0578b773672fa4e607ca0 100644 (file)
@@ -29,6 +29,7 @@ else
    bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
    if [ "$CONFIG_SUN4" != "y" ]; then
       bool '  Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI
+      source drivers/pci/Config.in
    fi
 
    mainmenu_option next_comment
index 98d1431a53c1792cd2b125403e9e04088b5ec8a1..1c14e11ff692ae097729b80e215b2f1be725a9cf 100644 (file)
@@ -23,6 +23,7 @@ CONFIG_VT_CONSOLE=y
 # CONFIG_SMP is not set
 # CONFIG_SUN4 is not set
 # CONFIG_PCI is not set
+# CONFIG_PCI_NAMES is not set
 
 #
 # Console drivers
index 86e9425975bac683b7e2cb21f1b4c8875fc4b069..01fc2e43a5ed0a2a53709288bb829a9a650c6180 100644 (file)
@@ -37,6 +37,7 @@ define_bool CONFIG_SUN_CONSOLE y
 define_bool CONFIG_SUN_AUXIO y
 define_bool CONFIG_SUN_IO y
 bool 'PCI support' CONFIG_PCI
+source drivers/pci/Config.in
 source drivers/sbus/char/Config.in
 source drivers/sbus/audio/Config.in
 
index 59ab0b543e4170f01155e1fc4b85735ac0870b46..ef84238fd1a7d0296ca20ee9ec9c4fcb9fd6ce08 100644 (file)
@@ -60,6 +60,7 @@ CONFIG_SUN_CONSOLE=y
 CONFIG_SUN_AUXIO=y
 CONFIG_SUN_IO=y
 CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
 
 #
 # Misc Linux/SPARC drivers
index 81228715e7fc0a05e0bfd6a25d5b3a4eadae591e..cd81857786661d560bf89ac63f092338b43a127f 100644 (file)
@@ -226,4 +226,15 @@ if [ "$CONFIG_PCMCIA" != "n" ]; then
    source drivers/char/pcmcia/Config.in
 fi
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   dep_tristate '/dev/agpgart (AGP Support) (EXPERIMENTAL)' CONFIG_AGP m
+   if [ "$CONFIG_AGP" = "m" ]; then
+     bool '   Intel 440LX/BX/GX support' CONFIG_AGP_INTEL
+     bool '   Intel I810/I810 DC100/I810e support' CONFIG_AGP_I810
+     bool '   VIA VP3/MVP3/Apollo Pro support' CONFIG_AGP_VIA
+     bool '   AMD Irongate support' CONFIG_AGP_AMD
+     bool '   Generic SiS support' CONFIG_AGP_SIS
+     bool '   ALI M1541 support' CONFIG_AGP_ALI
+   fi
+fi
 endmenu
index 7fdff597d28e5611fb1b7b5bca57eb4195c64a5a..38c4bc55fd40e9fcb6d75ec479f56ba3fca4682f 100644 (file)
@@ -636,6 +636,11 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_AGP), m)
+  ALL_SUB_DIRS += agp
+  MOD_SUB_DIRS += agp
+endif
+
 include $(TOPDIR)/Rules.make
 
 fastdep:
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
new file mode 100644 (file)
index 0000000..c03310f
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Makefile for the agpgart device driver.  This driver adds a user
+# space ioctl interface to use agp memory.  It also adds a kernel interface
+# that other drivers could use to manipulate agp memory.
+
+M_OBJS         := agpgart.o
+
+CFLAGS_agp_backend.o   :=
+
+ifdef CONFIG_AGP_I810
+CFLAGS_agp_backend.o   += -DAGP_BUILD_INTEL_I810
+endif
+ifdef CONFIG_AGP_INTEL
+CFLAGS_agp_backend.o   += -DAGP_BUILD_INTEL_GENERIC
+endif
+ifdef CONFIG_AGP_VIA
+CFLAGS_agp_backend.o   += -DAGP_BUILD_VIA_GENERIC
+endif
+ifdef CONFIG_AGP_AMD
+CFLAGS_agp_backend.o   += -DAGP_BUILD_AMD_IRONGATE
+endif
+ifdef CONFIG_AGP_SIS
+CFLAGS_agp_backend.o   += -DAGP_BUILD_SIS_GENERIC
+endif
+ifdef CONFIG_AGP_ALI
+CFLAGS_agp_backend.o   += -DAGP_BUILD_ALI_M1541
+endif
+
+include $(TOPDIR)/Rules.make
+
+agpgart.o: agp_backend.o agpgart_fe.o
+       $(LD) $(LD_RFLAG) -r -o $@ agp_backend.o agpgart_fe.o
diff --git a/drivers/char/agp/agp_backend.c b/drivers/char/agp/agp_backend.c
new file mode 100644 (file)
index 0000000..246cbbb
--- /dev/null
@@ -0,0 +1,1987 @@
+/*
+ * AGPGART module version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight
+ * Copyright (C) 1999 Xi Graphics
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ */
+#define EXPORT_SYMTAB
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/miscdevice.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/page.h>
+
+#include <linux/agp_backend.h>
+#include "agp_backendP.h"
+
+static struct agp_bridge_data agp_bridge;
+
+#define CACHE_FLUSH agp_bridge.cache_flush
+
+MODULE_AUTHOR("Jeff Hartmann <jhartmann@precisioninsight.com>");
+MODULE_PARM(agp_try_unsupported, "1i");
+EXPORT_SYMBOL(agp_free_memory);
+EXPORT_SYMBOL(agp_allocate_memory);
+EXPORT_SYMBOL(agp_copy_info);
+EXPORT_SYMBOL(agp_bind_memory);
+EXPORT_SYMBOL(agp_unbind_memory);
+EXPORT_SYMBOL(agp_enable);
+EXPORT_SYMBOL(agp_backend_acquire);
+EXPORT_SYMBOL(agp_backend_release);
+
+static int agp_try_unsupported __initdata = 0;
+
+#ifdef __SMP__
+static atomic_t cpus_waiting;
+#endif
+
+int agp_backend_acquire(void)
+{
+       atomic_inc(&(agp_bridge.agp_in_use));
+
+       if (atomic_read(&(agp_bridge.agp_in_use)) != 1) {
+               atomic_dec(&(agp_bridge.agp_in_use));
+               return -EBUSY;
+       }
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+void agp_backend_release(void)
+{
+       atomic_dec(&(agp_bridge.agp_in_use));
+       MOD_DEC_USE_COUNT;
+}
+
+static void flush_cache(void)
+{
+       asm volatile ("wbinvd":::"memory");
+}
+
+#ifdef __SMP__
+static void ipi_handler(void *null)
+{
+       flush_cache();
+       atomic_dec(&cpus_waiting);
+       while (atomic_read(&cpus_waiting) > 0)
+               barrier();
+}
+
+static void smp_flush_cache(void)
+{
+       atomic_set(&cpus_waiting, smp_num_cpus - 1);
+       if (smp_call_function(ipi_handler, NULL, 1, 0) != 0)
+               panic("agpgart: timed out waiting for the other CPUs!\n");
+       flush_cache();
+       while (atomic_read(&cpus_waiting) > 0)
+               barrier();
+}
+#endif
+
+/* 
+ * Basic Page Allocation Routines -
+ * These routines handle page allocation
+ * and by default they reserve the allocated 
+ * memory.  They also handle incrementing the
+ * current_memory_agp value, Which is checked
+ * against a maximum value.
+ */
+
+static void *agp_alloc_page(void)
+{
+       void *pt;
+
+       pt = (void *) __get_free_page(GFP_KERNEL);
+       if (pt == NULL) {
+               return NULL;
+       }
+       atomic_inc(&(mem_map[MAP_NR(pt)].count));
+       set_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
+       atomic_inc(&(agp_bridge.current_memory_agp));
+       return pt;
+}
+
+static void agp_destroy_page(void *pt)
+{
+       if (pt == NULL)
+               return;
+
+       atomic_dec(&(mem_map[MAP_NR(pt)].count));
+       clear_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
+       wake_up(&mem_map[MAP_NR(pt)].wait);
+       free_page((unsigned long) pt);
+       atomic_dec(&(agp_bridge.current_memory_agp));
+}
+
+/* End Basic Page Allocation Routines */
+
+/* 
+ * Generic routines for handling agp_memory structures -
+ * They use the basic page allocation routines to do the
+ * brunt of the work.
+ */
+
+#define MAXKEY (4096 * 32)
+
+static void agp_free_key(int key)
+{
+
+       if (key < 0) {
+               return;
+       }
+       if (key < MAXKEY) {
+               clear_bit(key, agp_bridge.key_list);
+       }
+}
+
+static int agp_get_key(void)
+{
+       int bit;
+
+       bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
+       if (bit < MAXKEY) {
+               set_bit(bit, agp_bridge.key_list);
+               return bit;
+       }
+       return -1;
+}
+
+static agp_memory *agp_create_memory(int scratch_pages)
+{
+       agp_memory *new;
+
+       new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
+
+       if (new == NULL) {
+               return NULL;
+       }
+       memset(new, 0, sizeof(agp_memory));
+       new->key = agp_get_key();
+
+       if (new->key < 0) {
+               kfree(new);
+               return NULL;
+       }
+       new->memory = vmalloc(PAGE_SIZE * scratch_pages);
+
+       if (new->memory == NULL) {
+               agp_free_key(new->key);
+               kfree(new);
+               return NULL;
+       }
+       new->num_scratch_pages = scratch_pages;
+       return new;
+}
+
+void agp_free_memory(agp_memory * curr)
+{
+       int i;
+
+       if (curr == NULL) {
+               return;
+       }
+       if (curr->is_bound == TRUE) {
+               agp_unbind_memory(curr);
+       }
+       if (curr->type != 0) {
+               agp_bridge.free_by_type(curr);
+               MOD_DEC_USE_COUNT;
+               return;
+       }
+       if (curr->page_count != 0) {
+               for (i = 0; i < curr->page_count; i++) {
+                       curr->memory[i] &= ~(0x00000fff);
+                       agp_destroy_page((void *) phys_to_virt(curr->memory[i]));
+               }
+       }
+       agp_free_key(curr->key);
+       vfree(curr->memory);
+       kfree(curr);
+       MOD_DEC_USE_COUNT;
+}
+
+#define ENTRIES_PER_PAGE               (PAGE_SIZE / sizeof(unsigned long))
+
+agp_memory *agp_allocate_memory(size_t page_count, u32 type)
+{
+       int scratch_pages;
+       agp_memory *new;
+       int i;
+
+       if ((atomic_read(&(agp_bridge.current_memory_agp)) + page_count) >
+           agp_bridge.max_memory_agp) {
+               return NULL;
+       }
+       if (type != 0) {
+               new = agp_bridge.alloc_by_type(page_count, type);
+               return new;
+       }
+       scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
+
+       new = agp_create_memory(scratch_pages);
+
+       if (new == NULL) {
+               return NULL;
+       }
+       for (i = 0; i < page_count; i++) {
+               new->memory[i] = (unsigned long) agp_alloc_page();
+
+               if ((void *) new->memory[i] == NULL) {
+                       /* Free this structure */
+                       agp_free_memory(new);
+                       return NULL;
+               }
+               new->memory[i] =
+                   agp_bridge.mask_memory(virt_to_phys((void *) new->memory[i]), type);
+               new->page_count++;
+       }
+
+       MOD_INC_USE_COUNT;
+       return new;
+}
+
+/* End - Generic routines for handling agp_memory structures */
+
+static int agp_return_size(void)
+{
+       int current_size;
+       void *temp;
+
+       temp = agp_bridge.current_size;
+
+       switch (agp_bridge.size_type) {
+       case U8_APER_SIZE:
+               current_size = ((aper_size_info_8 *) temp)->size;
+               break;
+       case U16_APER_SIZE:
+               current_size = ((aper_size_info_16 *) temp)->size;
+               break;
+       case U32_APER_SIZE:
+               current_size = ((aper_size_info_32 *) temp)->size;
+               break;
+       case FIXED_APER_SIZE:
+               current_size = ((aper_size_info_fixed *) temp)->size;
+               break;
+       default:
+               current_size = 0;
+               break;
+       }
+
+       return current_size;
+}
+
+/* Routine to copy over information structure */
+
+void agp_copy_info(agp_kern_info * info)
+{
+       memset(info, 0, sizeof(agp_kern_info));
+       info->version.major = agp_bridge.version->major;
+       info->version.minor = agp_bridge.version->minor;
+       info->device = agp_bridge.dev;
+       info->chipset = agp_bridge.type;
+       info->mode = agp_bridge.mode;
+       info->aper_base = agp_bridge.gart_bus_addr;
+       info->aper_size = agp_return_size();
+       info->max_memory = agp_bridge.max_memory_agp;
+       info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
+}
+
+/* End - Routine to copy over information structure */
+
+/*
+ * Routines for handling swapping of agp_memory into the GATT -
+ * These routines take agp_memory and insert them into the GATT.
+ * They call device specific routines to actually write to the GATT.
+ */
+
+int agp_bind_memory(agp_memory * curr, off_t pg_start)
+{
+       int ret_val;
+
+       if ((curr == NULL) || (curr->is_bound == TRUE)) {
+               return -EINVAL;
+       }
+       if (curr->is_flushed == FALSE) {
+               CACHE_FLUSH();
+               curr->is_flushed = TRUE;
+       }
+       ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
+
+       if (ret_val != 0) {
+               return ret_val;
+       }
+       curr->is_bound = TRUE;
+       curr->pg_start = pg_start;
+       return 0;
+}
+
+int agp_unbind_memory(agp_memory * curr)
+{
+       int ret_val;
+
+       if (curr == NULL) {
+               return -EINVAL;
+       }
+       if (curr->is_bound != TRUE) {
+               return -EINVAL;
+       }
+       ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
+
+       if (ret_val != 0) {
+               return ret_val;
+       }
+       curr->is_bound = FALSE;
+       curr->pg_start = 0;
+       return 0;
+}
+
+/* End - Routines for handling swapping of agp_memory into the GATT */
+
+/* 
+ * Driver routines - start
+ * Currently this module supports the 
+ * i810, 440lx, 440bx, 440gx, via vp3, via mvp3,
+ * amd irongate, ALi M1541 and generic support for the
+ * SiS chipsets.
+ */
+
+/* Generic Agp routines - Start */
+
+static void agp_generic_agp_enable(u32 mode)
+{
+       struct pci_dev *device = NULL;
+       u32 command, scratch, cap_id;
+       u8 cap_ptr;
+
+       pci_read_config_dword(agp_bridge.dev,
+                             agp_bridge.capndx + 4,
+                             &command);
+
+       /*
+        * PASS1: go throu all devices that claim to be
+        *        AGP devices and collect their data.
+        */
+
+       while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
+               pci_read_config_dword(device, 0x04, &scratch);
+
+               if (!(scratch & 0x00100000))
+                       continue;
+
+               pci_read_config_byte(device, 0x34, &cap_ptr);
+
+               if (cap_ptr != 0x00) {
+                       do {
+                               pci_read_config_dword(device, cap_ptr, &cap_id);
+
+                               if ((cap_id & 0xff) != 0x02)
+                                       cap_ptr = (cap_id >> 8) & 0xff;
+                       }
+                       while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+               }
+               if (cap_ptr != 0x00) {
+                       /*
+                        * Ok, here we have a AGP device. Disable impossible settings,
+                        * and adjust the readqueue to the minimum.
+                        */
+
+                       pci_read_config_dword(device, cap_ptr + 4, &scratch);
+
+                       /* adjust RQ depth */
+                       command =
+                           ((command & ~0xff000000) |
+                            min((mode & 0xff000000), min((command & 0xff000000), (scratch & 0xff000000))));
+
+                       /* disable SBA if it's not supported */
+                       if (!((command & 0x00000200) && (scratch & 0x00000200) && (mode & 0x00000200)))
+                               command &= ~0x00000200;
+
+                       /* disable FW if it's not supported */
+                       if (!((command & 0x00000010) && (scratch & 0x00000010) && (mode & 0x00000010)))
+                               command &= ~0x00000010;
+
+                       if (!((command & 4) && (scratch & 4) && (mode & 4)))
+                               command &= ~0x00000004;
+
+                       if (!((command & 2) && (scratch & 2) && (mode & 2)))
+                               command &= ~0x00000002;
+
+                       if (!((command & 1) && (scratch & 1) && (mode & 1)))
+                               command &= ~0x00000001;
+               }
+       }
+       /*
+        * PASS2: Figure out the 4X/2X/1X setting and enable the
+        *        target (our motherboard chipset).
+        */
+
+       if (command & 4) {
+               command &= ~3;  /* 4X */
+       }
+       if (command & 2) {
+               command &= ~5;  /* 2X */
+       }
+       if (command & 1) {
+               command &= ~6;  /* 1X */
+       }
+       command |= 0x00000100;
+
+       pci_write_config_dword(agp_bridge.dev,
+                              agp_bridge.capndx + 8,
+                              command);
+
+       /*
+        * PASS3: Go throu all AGP devices and update the
+        *        command registers.
+        */
+
+       while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
+               pci_read_config_dword(device, 0x04, &scratch);
+
+               if (!(scratch & 0x00100000))
+                       continue;
+
+               pci_read_config_byte(device, 0x34, &cap_ptr);
+
+               if (cap_ptr != 0x00) {
+                       do {
+                               pci_read_config_dword(device, cap_ptr, &cap_id);
+
+                               if ((cap_id & 0xff) != 0x02)
+                                       cap_ptr = (cap_id >> 8) & 0xff;
+                       }
+                       while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+               }
+               if (cap_ptr != 0x00)
+                       pci_write_config_dword(device, cap_ptr + 8, command);
+       }
+}
+
+static int agp_generic_create_gatt_table(void)
+{
+       char *table;
+       char *table_end;
+       int size;
+       int page_order;
+       int num_entries;
+       int i;
+       void *temp;
+
+       table = NULL;
+       i = agp_bridge.aperture_size_idx;
+       temp = agp_bridge.current_size;
+       size = page_order = num_entries = 0;
+
+       if (agp_bridge.size_type != FIXED_APER_SIZE) {
+               do {
+                       switch (agp_bridge.size_type) {
+                       case U8_APER_SIZE:
+                               size = ((aper_size_info_8 *) temp)->size;
+                               page_order = ((aper_size_info_8 *) temp)->page_order;
+                               num_entries = ((aper_size_info_8 *) temp)->num_entries;
+                               break;
+                       case U16_APER_SIZE:
+                               size = ((aper_size_info_16 *) temp)->size;
+                               page_order = ((aper_size_info_16 *) temp)->page_order;
+                               num_entries = ((aper_size_info_16 *) temp)->num_entries;
+                               break;
+                       case U32_APER_SIZE:
+                               size = ((aper_size_info_32 *) temp)->size;
+                               page_order = ((aper_size_info_32 *) temp)->page_order;
+                               num_entries = ((aper_size_info_32 *) temp)->num_entries;
+                               break;
+                               /* This case will never really happen */
+                       case FIXED_APER_SIZE:
+                       default:
+                               size = page_order = num_entries = 0;
+                               break;
+                       }
+
+                       table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+
+                       if (table == NULL) {
+                               i++;
+
+                               switch (agp_bridge.size_type) {
+                               case U8_APER_SIZE:
+                                       agp_bridge.current_size = (((aper_size_info_8 *) agp_bridge.aperture_sizes) + i);
+                                       break;
+                               case U16_APER_SIZE:
+                                       agp_bridge.current_size = (((aper_size_info_16 *) agp_bridge.aperture_sizes) + i);
+                                       break;
+                               case U32_APER_SIZE:
+                                       agp_bridge.current_size = (((aper_size_info_32 *) agp_bridge.aperture_sizes) + i);
+                                       break;
+                                       /* This case will never really happen */
+                               case FIXED_APER_SIZE:
+                               default:
+                                       size = page_order = num_entries = 0;
+                                       break;
+                               }
+                       } else {
+                               agp_bridge.aperture_size_idx = i;
+                       }
+               } while ((table == NULL) && (i < agp_bridge.num_aperture_sizes));
+       } else {
+               size = ((aper_size_info_fixed *) temp)->size;
+               page_order = ((aper_size_info_fixed *) temp)->page_order;
+               num_entries = ((aper_size_info_fixed *) temp)->num_entries;
+               table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+       }
+
+       if (table == NULL) {
+               return -ENOMEM;
+       }
+       table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+       for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
+               set_bit(PG_reserved, &mem_map[i].flags);
+       }
+
+       agp_bridge.gatt_table_real = (unsigned long *) table;
+       CACHE_FLUSH();
+       agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
+                                       (PAGE_SIZE * (1 << page_order)));
+       CACHE_FLUSH();
+
+       if (agp_bridge.gatt_table == NULL) {
+               for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
+                       clear_bit(PG_reserved, &mem_map[i].flags);
+               }
+
+               free_pages((unsigned long) table, page_order);
+
+               return -ENOMEM;
+       }
+       agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
+
+       for (i = 0; i < num_entries; i++) {
+               agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
+       }
+
+       return 0;
+}
+
+static int agp_generic_free_gatt_table(void)
+{
+       int i;
+       int page_order;
+       char *table, *table_end;
+       void *temp;
+
+       temp = agp_bridge.current_size;
+
+       switch (agp_bridge.size_type) {
+       case U8_APER_SIZE:
+               page_order = ((aper_size_info_8 *) temp)->page_order;
+               break;
+       case U16_APER_SIZE:
+               page_order = ((aper_size_info_16 *) temp)->page_order;
+               break;
+       case U32_APER_SIZE:
+               page_order = ((aper_size_info_32 *) temp)->page_order;
+               break;
+       case FIXED_APER_SIZE:
+               page_order = ((aper_size_info_fixed *) temp)->page_order;
+               break;
+       default:
+               page_order = 0;
+               break;
+       }
+
+       /* Do not worry about freeing memory, because if this is
+        * called, then all agp memory is deallocated and removed
+        * from the table.
+        */
+
+       iounmap(agp_bridge.gatt_table);
+       table = (char *) agp_bridge.gatt_table_real;
+       table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+       for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
+               clear_bit(PG_reserved, &mem_map[i].flags);
+       }
+
+       free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
+       return 0;
+}
+
+static int agp_generic_insert_memory(agp_memory * mem,
+                                    off_t pg_start, int type)
+{
+       int i, j, num_entries;
+       void *temp;
+
+       temp = agp_bridge.current_size;
+
+       switch (agp_bridge.size_type) {
+       case U8_APER_SIZE:
+               num_entries = ((aper_size_info_8 *) temp)->num_entries;
+               break;
+       case U16_APER_SIZE:
+               num_entries = ((aper_size_info_16 *) temp)->num_entries;
+               break;
+       case U32_APER_SIZE:
+               num_entries = ((aper_size_info_32 *) temp)->num_entries;
+               break;
+       case FIXED_APER_SIZE:
+               num_entries = ((aper_size_info_fixed *) temp)->num_entries;
+               break;
+       default:
+               num_entries = 0;
+               break;
+       }
+
+       if (type != 0 || mem->type != 0) {
+               /* The generic routines know nothing of memory types */
+               return -EINVAL;
+       }
+       if ((pg_start + mem->page_count) > num_entries) {
+               return -EINVAL;
+       }
+       j = pg_start;
+
+       while (j < (pg_start + mem->page_count)) {
+               if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+                       return -EBUSY;
+               }
+               j++;
+       }
+
+       if (mem->is_flushed == FALSE) {
+               CACHE_FLUSH();
+               mem->is_flushed = TRUE;
+       }
+       for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+               agp_bridge.gatt_table[j] = mem->memory[i];
+       }
+
+       agp_bridge.tlb_flush(mem);
+       return 0;
+}
+
+static int agp_generic_remove_memory(agp_memory * mem, off_t pg_start,
+                                    int type)
+{
+       int i;
+
+       if (type != 0 || mem->type != 0) {
+               /* The generic routines know nothing of memory types */
+               return -EINVAL;
+       }
+       for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+               agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
+       }
+
+       agp_bridge.tlb_flush(mem);
+       return 0;
+}
+
+static agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
+{
+       return NULL;
+}
+
+static void agp_generic_free_by_type(agp_memory * curr)
+{
+       if (curr->memory != NULL) {
+               vfree(curr->memory);
+       }
+       agp_free_key(curr->key);
+       kfree(curr);
+}
+
+void agp_enable(u32 mode)
+{
+       agp_bridge.agp_enable(mode);
+}
+
+/* End - Generic Agp routines */
+
+#ifdef AGP_BUILD_INTEL_I810
+
+static aper_size_info_fixed intel_i810_sizes[] =
+{
+       {64, 16384, 4},
+     /* The 32M mode still requires a 64k gatt */
+       {32, 8192, 4}
+};
+
+#define AGP_DCACHE_MEMORY 1
+
+static gatt_mask intel_i810_masks[] =
+{
+       {I810_PTE_VALID, 0},
+       {(I810_PTE_VALID | I810_PTE_LOCAL), AGP_DCACHE_MEMORY}
+};
+
+static struct _intel_i810_private {
+       struct pci_dev *i810_dev;       /* device one */
+       volatile unsigned char *registers;
+       int num_dcache_entries;
+} intel_i810_private;
+
+static int intel_i810_fetch_size(void)
+{
+       u32 smram_miscc;
+       aper_size_info_fixed *values;
+
+       pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
+       values = (aper_size_info_fixed *) agp_bridge.aperture_sizes;
+
+       if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
+               printk("agpgart: i810 is disabled\n");
+               return 0;
+       }
+       if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
+               agp_bridge.previous_size =
+                   agp_bridge.current_size = (void *) (values + 1);
+               agp_bridge.aperture_size_idx = 1;
+               return values[1].size;
+       } else {
+               agp_bridge.previous_size =
+                   agp_bridge.current_size = (void *) (values);
+               agp_bridge.aperture_size_idx = 0;
+               return values[0].size;
+       }
+
+       return 0;
+}
+
+static int intel_i810_configure(void)
+{
+       aper_size_info_fixed *current_size;
+       u32 temp;
+       int i;
+
+       current_size = (aper_size_info_fixed *) agp_bridge.current_size;
+
+       pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+       temp &= 0xfff80000;
+
+       intel_i810_private.registers =
+           (volatile unsigned char *) ioremap(temp, 128 * 4096);
+
+       if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
+            & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
+               /* This will need to be dynamically assigned */
+               printk("agpgart: detected 4MB dedicated video ram.\n");
+               intel_i810_private.num_dcache_entries = 1024;
+       }
+       pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
+                agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+       CACHE_FLUSH();
+
+       if (agp_bridge.needs_scratch_page == TRUE) {
+               for (i = 0; i < current_size->num_entries; i++) {
+                       OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
+                                agp_bridge.scratch_page);
+               }
+       }
+       return 0;
+}
+
+static void intel_i810_cleanup(void)
+{
+       OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
+       iounmap((void *) intel_i810_private.registers);
+}
+
+static void intel_i810_tlbflush(agp_memory * mem)
+{
+       return;
+}
+
+static void intel_i810_agp_enable(u32 mode)
+{
+       return;
+}
+
+static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
+                                    int type)
+{
+       int i, j, num_entries;
+       void *temp;
+
+       temp = agp_bridge.current_size;
+       num_entries = ((aper_size_info_fixed *) temp)->num_entries;
+
+       if ((pg_start + mem->page_count) > num_entries) {
+               return -EINVAL;
+       }
+       for (j = pg_start; j < (pg_start + mem->page_count); j++) {
+               if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+                       return -EBUSY;
+               }
+       }
+
+       if (type != 0 || mem->type != 0) {
+               if ((type == AGP_DCACHE_MEMORY) &&
+                   (mem->type == AGP_DCACHE_MEMORY)) {
+                       /* special insert */
+
+                       for (i = pg_start; i < (pg_start + mem->page_count); i++) {
+                               OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
+                                        (i * 4096) | I810_PTE_LOCAL | I810_PTE_VALID);
+                       }
+
+                       agp_bridge.tlb_flush(mem);
+                       return 0;
+               }
+               return -EINVAL;
+       }
+       if (mem->is_flushed == FALSE) {
+               CACHE_FLUSH();
+               mem->is_flushed = TRUE;
+       }
+       for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+               OUTREG32(intel_i810_private.registers,
+                        I810_PTE_BASE + (j * 4), mem->memory[i]);
+       }
+
+       agp_bridge.tlb_flush(mem);
+       return 0;
+}
+
+static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
+                                    int type)
+{
+       int i;
+
+       for (i = pg_start; i < (mem->page_count + pg_start); i++) {
+               OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
+                        agp_bridge.scratch_page);
+       }
+
+       agp_bridge.tlb_flush(mem);
+       return 0;
+}
+
+static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
+{
+       agp_memory *new;
+
+       if (type == AGP_DCACHE_MEMORY) {
+               if (pg_count != intel_i810_private.num_dcache_entries) {
+                       return NULL;
+               }
+               new = agp_create_memory(1);
+
+               if (new == NULL) {
+                       return NULL;
+               }
+               new->type = AGP_DCACHE_MEMORY;
+               new->page_count = pg_count;
+               new->num_scratch_pages = 0;
+               vfree(new->memory);
+               return new;
+       }
+       return NULL;
+}
+
+static void intel_i810_free_by_type(agp_memory * curr)
+{
+       agp_free_key(curr->key);
+       kfree(curr);
+}
+
+static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
+{
+       /* Type checking must be done elsewhere */
+       return addr | agp_bridge.masks[type].mask;
+}
+
+static void intel_i810_setup(struct pci_dev *i810_dev)
+{
+       intel_i810_private.i810_dev = i810_dev;
+
+       agp_bridge.masks = intel_i810_masks;
+       agp_bridge.num_of_masks = 2;
+       agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
+       agp_bridge.size_type = FIXED_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 2;
+       agp_bridge.dev_private_data = (void *) &intel_i810_private;
+       agp_bridge.needs_scratch_page = TRUE;
+       agp_bridge.configure = intel_i810_configure;
+       agp_bridge.fetch_size = intel_i810_fetch_size;
+       agp_bridge.cleanup = intel_i810_cleanup;
+       agp_bridge.tlb_flush = intel_i810_tlbflush;
+       agp_bridge.mask_memory = intel_i810_mask_memory;
+       agp_bridge.agp_enable = intel_i810_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = intel_i810_insert_entries;
+       agp_bridge.remove_memory = intel_i810_remove_entries;
+       agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
+       agp_bridge.free_by_type = intel_i810_free_by_type;
+}
+
+#endif
+
+#ifdef AGP_BUILD_INTEL_GENERIC
+
+static int intel_fetch_size(void)
+{
+       int i;
+       u16 temp;
+       aper_size_info_16 *values;
+
+       pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
+       (void *) values = agp_bridge.aperture_sizes;
+
+       for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+               if (temp == values[i].size_value) {
+                       agp_bridge.previous_size =
+                           agp_bridge.current_size = (void *) (values + i);
+                       agp_bridge.aperture_size_idx = i;
+                       return values[i].size;
+               }
+       }
+
+       return 0;
+}
+
+static void intel_tlbflush(agp_memory * mem)
+{
+       pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
+       pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+}
+
+static void intel_cleanup(void)
+{
+       u16 temp;
+       aper_size_info_16 *previous_size;
+
+       previous_size = (aper_size_info_16 *) agp_bridge.previous_size;
+       pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
+       pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
+       pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value);
+}
+
+static int intel_configure(void)
+{
+       u32 temp;
+       u16 temp2;
+       aper_size_info_16 *current_size;
+
+       current_size = (aper_size_info_16 *) agp_bridge.current_size;
+
+       /* aperture size */
+       pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+
+       /* address to map to */
+       pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+       /* attbase - aperture base */
+       pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+
+       /* agpctrl */
+       pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+
+       /* paccfg/nbxcfg */
+       pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
+       pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, (temp2 & ~(1 << 10)) | (1 << 9));
+       /* clear any possible error conditions */
+       pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
+       return 0;
+}
+
+static unsigned long intel_mask_memory(unsigned long addr, int type)
+{
+       /* Memory type is ignored */
+
+       return addr | agp_bridge.masks[0].mask;
+}
+
+
+/* Setup function */
+static gatt_mask intel_generic_masks[] =
+{
+       {0x00000017, 0}
+};
+
+static aper_size_info_16 intel_generic_sizes[7] =
+{
+       {256, 65536, 6, 0},
+       {128, 32768, 5, 32},
+       {64, 16384, 4, 48},
+       {32, 8192, 3, 56},
+       {16, 4096, 2, 60},
+       {8, 2048, 1, 62},
+       {4, 1024, 0, 63}
+};
+
+static void intel_generic_setup(void)
+{
+       agp_bridge.masks = intel_generic_masks;
+       agp_bridge.num_of_masks = 1;
+       agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
+       agp_bridge.size_type = U16_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 7;
+       agp_bridge.dev_private_data = NULL;
+       agp_bridge.needs_scratch_page = FALSE;
+       agp_bridge.configure = intel_configure;
+       agp_bridge.fetch_size = intel_fetch_size;
+       agp_bridge.cleanup = intel_cleanup;
+       agp_bridge.tlb_flush = intel_tlbflush;
+       agp_bridge.mask_memory = intel_mask_memory;
+       agp_bridge.agp_enable = agp_generic_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = agp_generic_insert_memory;
+       agp_bridge.remove_memory = agp_generic_remove_memory;
+       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+       agp_bridge.free_by_type = agp_generic_free_by_type;
+}
+
+#endif
+
+#ifdef AGP_BUILD_VIA_GENERIC
+
+static int via_fetch_size(void)
+{
+       int i;
+       u8 temp;
+       aper_size_info_8 *values;
+
+       (void *) values = agp_bridge.aperture_sizes;
+       pci_read_config_byte(agp_bridge.dev, VIA_APSIZE, &temp);
+       for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+               if (temp == values[i].size_value) {
+                       agp_bridge.previous_size =
+                           agp_bridge.current_size = (void *) (values + i);
+                       agp_bridge.aperture_size_idx = i;
+                       return values[i].size;
+               }
+       }
+
+       return 0;
+}
+
+static int via_configure(void)
+{
+       u32 temp;
+       aper_size_info_8 *current_size;
+
+       current_size = (aper_size_info_8 *) agp_bridge.current_size;
+       /* aperture size */
+       pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, current_size->size_value);
+       /* address to map too */
+       pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+       /* GART control register */
+       pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
+
+       /* attbase - aperture GATT base */
+       pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE,
+                           (agp_bridge.gatt_bus_addr & 0xfffff000) | 3);
+       return 0;
+}
+
+static void via_cleanup(void)
+{
+       aper_size_info_8 *previous_size;
+
+       previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
+       pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE, 0);
+       pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, previous_size->size_value);
+}
+
+static void via_tlbflush(agp_memory * mem)
+{
+       pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000008f);
+       pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
+}
+
+static unsigned long via_mask_memory(unsigned long addr, int type)
+{
+       /* Memory type is ignored */
+
+       return addr | agp_bridge.masks[0].mask;
+}
+
+static aper_size_info_8 via_generic_sizes[7] =
+{
+       {256, 65536, 6, 0},
+       {128, 32768, 5, 128},
+       {64, 16384, 4, 192},
+       {32, 8192, 3, 224},
+       {16, 4096, 2, 240},
+       {8, 2048, 1, 248},
+       {4, 1024, 0, 252}
+};
+
+static gatt_mask via_generic_masks[] =
+{
+       {0x00000000, 0}
+};
+
+static void via_generic_setup(void)
+{
+       agp_bridge.masks = via_generic_masks;
+       agp_bridge.num_of_masks = 1;
+       agp_bridge.aperture_sizes = (void *) via_generic_sizes;
+       agp_bridge.size_type = U8_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 7;
+       agp_bridge.dev_private_data = NULL;
+       agp_bridge.needs_scratch_page = FALSE;
+       agp_bridge.configure = via_configure;
+       agp_bridge.fetch_size = via_fetch_size;
+       agp_bridge.cleanup = via_cleanup;
+       agp_bridge.tlb_flush = via_tlbflush;
+       agp_bridge.mask_memory = via_mask_memory;
+       agp_bridge.agp_enable = agp_generic_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = agp_generic_insert_memory;
+       agp_bridge.remove_memory = agp_generic_remove_memory;
+       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+       agp_bridge.free_by_type = agp_generic_free_by_type;
+}
+
+#endif
+
+#ifdef AGP_BUILD_SIS_GENERIC
+
+static int sis_fetch_size(void)
+{
+       u8 temp_size;
+       int i;
+       aper_size_info_8 *values;
+
+       pci_read_config_byte(agp_bridge.dev, SIS_APSIZE, &temp_size);
+       (void *) values = agp_bridge.aperture_sizes;
+       for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+               if ((temp_size == values[i].size_value) ||
+                   ((temp_size & ~(0x03)) == (values[i].size_value & ~(0x03)))) {
+                       agp_bridge.previous_size =
+                           agp_bridge.current_size = (void *) (values + i);
+
+                       agp_bridge.aperture_size_idx = i;
+                       return values[i].size;
+               }
+       }
+
+       return 0;
+}
+
+
+static void sis_tlbflush(agp_memory * mem)
+{
+       pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02);
+}
+
+static int sis_configure(void)
+{
+       u32 temp;
+       aper_size_info_8 *current_size;
+
+       current_size = (aper_size_info_8 *) agp_bridge.current_size;
+       pci_write_config_byte(agp_bridge.dev, SIS_TLBCNTRL, 0x05);
+       pci_read_config_dword(agp_bridge.dev, SIS_APBASE, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       pci_write_config_dword(agp_bridge.dev, SIS_ATTBASE, agp_bridge.gatt_bus_addr);
+       pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, current_size->size_value);
+       return 0;
+}
+
+static void sis_cleanup(void)
+{
+       aper_size_info_8 *previous_size;
+
+       previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
+       pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, (previous_size->size_value & ~(0x03)));
+}
+
+static unsigned long sis_mask_memory(unsigned long addr, int type)
+{
+       /* Memory type is ignored */
+
+       return addr | agp_bridge.masks[0].mask;
+}
+
+static aper_size_info_8 sis_generic_sizes[7] =
+{
+       {256, 65536, 6, 99},
+       {128, 32768, 5, 83},
+       {64, 16384, 4, 67},
+       {32, 8192, 3, 51},
+       {16, 4096, 2, 35},
+       {8, 2048, 1, 19},
+       {4, 1024, 0, 3}
+};
+
+static gatt_mask sis_generic_masks[] =
+{
+       {0x00000000, 0}
+};
+
+static void sis_generic_setup(void)
+{
+       agp_bridge.masks = sis_generic_masks;
+       agp_bridge.num_of_masks = 1;
+       agp_bridge.aperture_sizes = (void *) sis_generic_sizes;
+       agp_bridge.size_type = U8_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 7;
+       agp_bridge.dev_private_data = NULL;
+       agp_bridge.needs_scratch_page = FALSE;
+       agp_bridge.configure = sis_configure;
+       agp_bridge.fetch_size = sis_fetch_size;
+       agp_bridge.cleanup = sis_cleanup;
+       agp_bridge.tlb_flush = sis_tlbflush;
+       agp_bridge.mask_memory = sis_mask_memory;
+       agp_bridge.agp_enable = agp_generic_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = agp_generic_insert_memory;
+       agp_bridge.remove_memory = agp_generic_remove_memory;
+       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+       agp_bridge.free_by_type = agp_generic_free_by_type;
+}
+
+#endif
+
+#ifdef AGP_BUILD_AMD_IRONGATE
+
+static struct _amd_irongate_private {
+       volatile unsigned char *registers;
+} amd_irongate_private;
+
+static int amd_irongate_fetch_size(void)
+{
+       int i;
+       u32 temp;
+       aper_size_info_32 *values;
+
+       pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+       temp = (temp & 0x0000000e);
+       (void *) values = agp_bridge.aperture_sizes;
+       for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+               if (temp == values[i].size_value) {
+                       agp_bridge.previous_size =
+                           agp_bridge.current_size = (void *) (values + i);
+
+                       agp_bridge.aperture_size_idx = i;
+                       return values[i].size;
+               }
+       }
+
+       return 0;
+}
+
+static int amd_irongate_configure(void)
+{
+       aper_size_info_32 *current_size;
+       u32 temp;
+       u16 enable_reg;
+
+       current_size = (aper_size_info_32 *) agp_bridge.current_size;
+
+       /* Get the memory mapped registers */
+       pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
+       temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       amd_irongate_private.registers = (volatile unsigned char *) ioremap(temp, 4096);
+
+       /* Write out the address of the gatt table */
+       OUTREG32(amd_irongate_private.registers, AMD_ATTBASE, agp_bridge.gatt_bus_addr);
+
+       /* Write the Sync register */
+       pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
+
+       /* Write the enable register */
+       enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+       enable_reg = (enable_reg | 0x0004);
+       OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+
+       /* Write out the size register */
+       pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+       temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 0x00000001);
+       pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+
+       /* Flush the tlb */
+       OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
+
+       /* Get the address for the gart region */
+       pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
+       temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       agp_bridge.gart_bus_addr = temp;
+       return 0;
+}
+
+static void amd_irongate_cleanup(void)
+{
+       aper_size_info_32 *previous_size;
+       u32 temp;
+       u16 enable_reg;
+
+       previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
+
+       enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
+       enable_reg = (enable_reg & ~(0x0004));
+       OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
+
+       /* Write back the previous size and disable gart translation */
+       pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+       temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
+       pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+       iounmap((void *) amd_irongate_private.registers);
+}
+
+/*
+ * This routine could be implemented by taking the addresses
+ * written to the GATT, and flushing them individually.  However
+ * currently it just flushes the whole table.  Which is probably
+ * more efficent, since agp_memory blocks can be a large number of
+ * entries.
+ */
+
+static void amd_irongate_tlbflush(agp_memory * temp)
+{
+       OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
+}
+
+static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
+{
+       /* Only type 0 is supported by the irongate */
+
+       return addr | agp_bridge.masks[0].mask;
+}
+
+static aper_size_info_32 amd_irongate_sizes[7] =
+{
+       {2048, 524288, 9, 0x0000000c},
+       {1024, 262144, 8, 0x0000000a},
+       {512, 131072, 7, 0x00000008},
+       {256, 65536, 6, 0x00000006},
+       {128, 32768, 5, 0x00000004},
+       {64, 16384, 4, 0x00000002},
+       {32, 8192, 3, 0x00000000}
+};
+
+static gatt_mask amd_irongate_masks[] =
+{
+       {0x00000001, 0}
+};
+
+static void amd_irongate_setup(void)
+{
+       agp_bridge.masks = amd_irongate_masks;
+       agp_bridge.num_of_masks = 1;
+       agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
+       agp_bridge.size_type = U32_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 7;
+       agp_bridge.dev_private_data = (void *) &amd_irongate_private;
+       agp_bridge.needs_scratch_page = FALSE;
+       agp_bridge.configure = amd_irongate_configure;
+       agp_bridge.fetch_size = amd_irongate_fetch_size;
+       agp_bridge.cleanup = amd_irongate_cleanup;
+       agp_bridge.tlb_flush = amd_irongate_tlbflush;
+       agp_bridge.mask_memory = amd_irongate_mask_memory;
+       agp_bridge.agp_enable = agp_generic_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = agp_generic_insert_memory;
+       agp_bridge.remove_memory = agp_generic_remove_memory;
+       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+       agp_bridge.free_by_type = agp_generic_free_by_type;
+}
+
+#endif
+
+#ifdef AGP_BUILD_ALI_M1541
+
+static int ali_fetch_size(void)
+{
+       int i;
+       u32 temp;
+       aper_size_info_32 *values;
+
+       pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp);
+       temp &= ~(0xfffffff0);
+       (void *) values = agp_bridge.aperture_sizes;
+
+       for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+               if (temp == values[i].size_value) {
+                       agp_bridge.previous_size =
+                           agp_bridge.current_size = (void *) (values + i);
+                       agp_bridge.aperture_size_idx = i;
+                       return values[i].size;
+               }
+       }
+
+       return 0;
+}
+
+static void ali_tlbflush(agp_memory * mem)
+{
+       u32 temp;
+
+       pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+       pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
+                              ((temp & 0xffffff00) | 0x00000090));
+       pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
+                              ((temp & 0xffffff00) | 0x00000010));
+}
+
+static void ali_cleanup(void)
+{
+       aper_size_info_32 *previous_size;
+       u32 temp;
+
+       previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
+
+       pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+       pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
+                              ((temp & 0xffffff00) | 0x00000090));
+       pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, previous_size->size_value);
+}
+
+static int ali_configure(void)
+{
+       u32 temp;
+       aper_size_info_32 *current_size;
+
+       current_size = (aper_size_info_32 *) agp_bridge.current_size;
+
+       /* aperture size and gatt addr */
+       pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE,
+                   agp_bridge.gatt_bus_addr | current_size->size_value);
+
+       /* tlb control */
+       pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+       pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
+                              ((temp & 0xffffff00) | 0x00000010));
+
+       /* address to map to */
+       pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
+       agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       return 0;
+}
+
+static unsigned long ali_mask_memory(unsigned long addr, int type)
+{
+       /* Memory type is ignored */
+
+       return addr | agp_bridge.masks[0].mask;
+}
+
+
+/* Setup function */
+static gatt_mask ali_generic_masks[] =
+{
+       {0x00000000, 0}
+};
+
+static aper_size_info_32 ali_generic_sizes[7] =
+{
+       {256, 65536, 6, 10},
+       {128, 32768, 5, 9},
+       {64, 16384, 4, 8},
+       {32, 8192, 3, 7},
+       {16, 4096, 2, 6},
+       {8, 2048, 1, 4},
+       {4, 1024, 0, 3}
+};
+
+static void ali_generic_setup(void)
+{
+       agp_bridge.masks = ali_generic_masks;
+       agp_bridge.num_of_masks = 1;
+       agp_bridge.aperture_sizes = (void *) ali_generic_sizes;
+       agp_bridge.size_type = U32_APER_SIZE;
+       agp_bridge.num_aperture_sizes = 7;
+       agp_bridge.dev_private_data = NULL;
+       agp_bridge.needs_scratch_page = FALSE;
+       agp_bridge.configure = ali_configure;
+       agp_bridge.fetch_size = ali_fetch_size;
+       agp_bridge.cleanup = ali_cleanup;
+       agp_bridge.tlb_flush = ali_tlbflush;
+       agp_bridge.mask_memory = ali_mask_memory;
+       agp_bridge.agp_enable = agp_generic_agp_enable;
+#ifdef __SMP__
+       agp_bridge.cache_flush = smp_flush_cache;
+#else
+       agp_bridge.cache_flush = flush_cache;
+#endif
+       agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+       agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+       agp_bridge.insert_memory = agp_generic_insert_memory;
+       agp_bridge.remove_memory = agp_generic_remove_memory;
+       agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+       agp_bridge.free_by_type = agp_generic_free_by_type;
+}
+
+#endif
+
+
+
+/* Supported Device Scanning routine */
+
+static void agp_find_supported_device(void)
+{
+       struct pci_dev *dev = NULL;
+       u8 cap_ptr = 0x00;
+       u32 cap_id, scratch;
+
+       if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL) {
+               agp_bridge.type = NOT_SUPPORTED;
+               return;
+       }
+       agp_bridge.dev = dev;
+
+       /* Need to test for I810 here */
+#ifdef AGP_BUILD_INTEL_I810
+       if (dev->vendor == PCI_VENDOR_ID_INTEL) {
+               struct pci_dev *i810_dev;
+
+               switch (dev->device) {
+               case PCI_DEVICE_ID_INTEL_810_0:
+                       i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+                                              PCI_DEVICE_ID_INTEL_810_1,
+                                                  NULL);
+                       if (i810_dev == NULL) {
+                               printk("agpgart: Detected an Intel i810, but could not find the secondary device.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+                       printk("agpgart: Detected an Intel i810 Chipset.\n");
+                       agp_bridge.type = INTEL_I810;
+                       agp_bridge.intel_i810_setup(i810_dev);
+                       return;
+
+               case PCI_DEVICE_ID_INTEL_810_DC100_0:
+                       i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+                                        PCI_DEVICE_ID_INTEL_810_DC100_1,
+                                                  NULL);
+                       if (i810_dev == NULL) {
+                               printk("agpgart: Detected an Intel i810 DC100, but could not find the secondary device.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+                       printk("agpgart: Detected an Intel i810 DC100 Chipset.\n");
+                       agp_bridge.type = INTEL_I810;
+                       agp_bridge.intel_i810_setup(i810_dev);
+                       return;
+
+               case PCI_DEVICE_ID_INTEL_810_E_0:
+                       i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
+                                            PCI_DEVICE_ID_INTEL_810_E_1,
+                                                  NULL);
+                       if (i810_dev == NULL) {
+                               printk("agpgart: Detected an Intel i810 E, but could not find the secondary device.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+                       printk("agpgart: Detected an Intel i810 E Chipset.\n");
+                       agp_bridge.type = INTEL_I810;
+                       agp_bridge.intel_i810_setup(i810_dev);
+                       return;
+               default:
+                       break;
+               }
+       }
+#endif
+       /* find capndx */
+       pci_read_config_dword(dev, 0x04, &scratch);
+
+       if (!(scratch & 0x00100000)) {
+               agp_bridge.type = NOT_SUPPORTED;
+               return;
+       }
+       pci_read_config_byte(dev, 0x34, &cap_ptr);
+
+       if (cap_ptr != 0x00) {
+               do {
+                       pci_read_config_dword(dev, cap_ptr, &cap_id);
+
+                       if ((cap_id & 0xff) != 0x02)
+                               cap_ptr = (cap_id >> 8) & 0xff;
+               }
+               while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+       }
+       if (cap_ptr == 0x00) {
+               agp_bridge.type = NOT_SUPPORTED;
+               return;
+       }
+       agp_bridge.capndx = cap_ptr;
+
+       /* Fill in the mode register */
+       pci_read_config_dword(agp_bridge.dev,
+                             agp_bridge.capndx + 4,
+                             &agp_bridge.mode);
+
+       switch (dev->vendor) {
+#ifdef AGP_BUILD_INTEL_GENERIC
+       case PCI_VENDOR_ID_INTEL:
+               switch (dev->device) {
+               case PCI_DEVICE_ID_INTEL_82443LX_0:
+                       agp_bridge.type = INTEL_LX;
+                       printk("agpgart: Detected an Intel 440LX Chipset.\n");
+                       agp_bridge.intel_generic_setup();
+                       return;
+
+               case PCI_DEVICE_ID_INTEL_82443BX_0:
+                       agp_bridge.type = INTEL_BX;
+                       printk("agpgart: Detected an Intel 440BX Chipset.\n");
+                       agp_bridge.intel_generic_setup();
+                       return;
+
+               case PCI_DEVICE_ID_INTEL_82443GX_0:
+                       agp_bridge.type = INTEL_GX;
+                       printk("agpgart: Detected an Intel 440GX Chipset.\n");
+                       agp_bridge.intel_generic_setup();
+                       return;
+
+               default:
+                       if (agp_try_unsupported != 0) {
+                               printk("agpgart: Trying generic intel routines for device id: %x\n", dev->device);
+                               agp_bridge.type = INTEL_GENERIC;
+                               agp_bridge.intel_generic_setup();
+                               return;
+                       } else {
+                               printk("agpgart: Unsupported intel chipset, you might want to try agp_try_unsupported=1.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+               }
+               break;
+#endif
+
+#ifdef AGP_BUILD_VIA_GENERIC
+       case PCI_VENDOR_ID_VIA:
+               switch (dev->device) {
+               case PCI_DEVICE_ID_VIA_82C597_0:
+                       agp_bridge.type = VIA_VP3;
+                       printk("agpgart: Detected a VIA VP3 Chipset.\n");
+                       agp_bridge.via_generic_setup();
+                       return;
+
+               case PCI_DEVICE_ID_VIA_82C598_0:
+                       agp_bridge.type = VIA_MVP3;
+                       printk("agpgart: Detected a VIA MVP3 Chipset.\n");
+                       agp_bridge.via_generic_setup();
+                       return;
+
+               case PCI_DEVICE_ID_VIA_82C691_0:
+                       agp_bridge.type = VIA_APOLLO_PRO;
+                       printk("agpgart: Detected a VIA Apollo Pro Chipset.\n");
+                       agp_bridge.via_generic_setup();
+                       return;
+
+               default:
+                       if (agp_try_unsupported != 0) {
+                               printk("agpgart: Trying generic VIA routines for device id: %x\n", dev->device);
+                               agp_bridge.type = VIA_GENERIC;
+                               agp_bridge.via_generic_setup();
+                               return;
+                       } else {
+                               printk("agpgart: Unsupported VIA chipset, you might want to try agp_try_unsupported=1.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+               }
+               break;
+#endif
+
+#ifdef AGP_BUILD_SIS_GENERIC
+       case PCI_VENDOR_ID_SI:
+               switch (dev->device) {
+                       /* ToDo need to find out the specific devices supported */
+               default:
+                       if (agp_try_unsupported != 0) {
+                               printk("agpgart: Trying generic SiS routines for device id: %x\n", dev->device);
+                               agp_bridge.type = SIS_GENERIC;
+                               agp_bridge.sis_generic_setup();
+                               return;
+                       } else {
+                               printk("agpgart: Unsupported SiS chipset, you might want to try agp_try_unsupported=1.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+               }
+               break;
+#endif
+
+#ifdef AGP_BUILD_AMD_IRONGATE
+       case PCI_VENDOR_ID_AMD:
+               switch (dev->device) {
+               case PCI_DEVICE_ID_AMD_IRONGATE_0:
+                       agp_bridge.type = AMD_IRONGATE;
+                       printk("agpgart: Detected an AMD Irongate Chipset.\n");
+                       agp_bridge.amd_irongate_setup();
+                       return;
+
+               default:
+                       if (agp_try_unsupported != 0) {
+                               printk("agpgart: Trying Amd irongate routines for device id: %x\n", dev->device);
+                               agp_bridge.type = AMD_GENERIC;
+                               agp_bridge.amd_irongate_setup();
+                               return;
+                       } else {
+                               printk("agpgart: Unsupported Amd chipset, you might want to try agp_try_unsupported=1.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+               }
+               break;
+#endif
+
+#ifdef AGP_BUILD_ALI_M1541
+       case PCI_VENDOR_ID_AL:
+               switch (dev->device) {
+               case PCI_DEVICE_ID_AL_M1541_0:
+                       agp_bridge.type = ALI_M1541;
+                       printk("agpgart: Detected an ALi M1541 Chipset\n");
+                       agp_bridge.ali_generic_setup();
+                       return;
+               default:
+                       if (agp_try_unsupported != 0) {
+                               printk("agpgart: Trying ALi generic routines for device id: %x\n", dev->device);
+                               agp_bridge.type = ALI_GENERIC;
+                               agp_bridge.ali_generic_setup();
+                               return;
+                       } else {
+                               printk("agpgart: Unsupported ALi chipset, you might want to type agp_try_unsupported=1.\n");
+                               agp_bridge.type = NOT_SUPPORTED;
+                               return;
+                       }
+               }
+               break;
+#endif
+       default:
+               agp_bridge.type = NOT_SUPPORTED;
+               return;
+       }
+}
+
+struct agp_max_table {
+       int mem;
+       int agp;
+};
+
+static struct agp_max_table agp_maxes_table[9] =
+{
+       {0, 0},
+       {32, 4},
+       {64, 28},
+       {128, 96},
+       {256, 204},
+       {512, 440},
+       {1024, 942},
+       {2048, 1920},
+       {4096, 3932}
+};
+
+static int agp_find_max(void)
+{
+       int memory;
+       float t;
+       int index;
+       int result;
+
+       memory = virt_to_phys(high_memory) / 0x100000;
+       index = 0;
+
+       while ((memory > agp_maxes_table[index].mem) &&
+              (index < 8)) {
+               index++;
+       }
+
+       t = (memory - agp_maxes_table[index - 1].mem) /
+           (agp_maxes_table[index].mem - agp_maxes_table[index - 1].mem);
+
+       result = agp_maxes_table[index - 1].agp +
+           (t * (agp_maxes_table[index].agp - agp_maxes_table[index - 1].agp));
+
+       printk("agpgart: Maximum main memory to use for agp memory: %dM\n", result);
+       result = (result * 0x100000) / 4096;
+       return result;
+}
+
+#define AGPGART_VERSION_MAJOR 0
+#define AGPGART_VERSION_MINOR 99
+
+static agp_version agp_current_version =
+{
+       AGPGART_VERSION_MAJOR,
+       AGPGART_VERSION_MINOR
+};
+
+static int agp_backend_initialize(void)
+{
+       int size_value;
+
+       memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
+       agp_bridge.type = NOT_SUPPORTED;
+#ifdef AGP_BUILD_INTEL_GENERIC
+       agp_bridge.intel_generic_setup = intel_generic_setup;
+#endif
+#ifdef AGP_BUILD_INTEL_I810
+       agp_bridge.intel_i810_setup = intel_i810_setup;
+#endif
+#ifdef AGP_BUILD_VIA_GENERIC
+       agp_bridge.via_generic_setup = via_generic_setup;
+#endif
+#ifdef AGP_BUILD_SIS_GENERIC
+       agp_bridge.sis_generic_setup = sis_generic_setup;
+#endif
+#ifdef AGP_BUILD_AMD_IRONGATE
+       agp_bridge.amd_irongate_setup = amd_irongate_setup;
+#endif
+#ifdef AGP_BUILD_ALI_M1541
+       agp_bridge.ali_generic_setup = ali_generic_setup;
+#endif
+       agp_bridge.max_memory_agp = agp_find_max();
+       agp_bridge.version = &agp_current_version;
+       agp_find_supported_device();
+
+       if (agp_bridge.needs_scratch_page == TRUE) {
+               agp_bridge.scratch_page = (unsigned long) agp_alloc_page();
+
+               if ((void *) (agp_bridge.scratch_page) == NULL) {
+                       printk("agpgart: unable to get memory for scratch page.\n");
+                       return -ENOMEM;
+               }
+               agp_bridge.scratch_page = virt_to_phys((void *) agp_bridge.scratch_page);
+               agp_bridge.scratch_page = agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
+       }
+       if (agp_bridge.type == NOT_SUPPORTED) {
+               printk("agpgart: no supported devices found.\n");
+               return -EINVAL;
+       }
+       size_value = agp_bridge.fetch_size();
+
+       if (size_value == 0) {
+               printk("agpgart: unable to detrimine aperture size.\n");
+               return -EINVAL;
+       }
+       if (agp_bridge.create_gatt_table()) {
+               printk("agpgart: unable to get memory for graphics translation table.\n");
+               return -ENOMEM;
+       }
+       agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
+
+       if (agp_bridge.key_list == NULL) {
+               printk("agpgart: error allocating memory for key lists.\n");
+               agp_bridge.free_gatt_table();
+               return -ENOMEM;
+       }
+       memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
+
+       if (agp_bridge.configure()) {
+               printk("agpgart: error configuring host chipset.\n");
+               agp_bridge.free_gatt_table();
+               vfree(agp_bridge.key_list);
+               return -EINVAL;
+       }
+       printk("agpgart: Physical address of the agp aperture: 0x%lx\n", agp_bridge.gart_bus_addr);
+       printk("agpgart: Agp aperture is %dM in size.\n", size_value);
+       return 0;
+}
+
+static void agp_backend_cleanup(void)
+{
+       agp_bridge.cleanup();
+       agp_bridge.free_gatt_table();
+       vfree(agp_bridge.key_list);
+
+       if (agp_bridge.needs_scratch_page == TRUE) {
+               agp_bridge.scratch_page &= ~(0x00000fff);
+               agp_destroy_page((void *) phys_to_virt(agp_bridge.scratch_page));
+       }
+}
+
+extern int agp_frontend_initialize(void);
+extern void agp_frontend_cleanup(void);
+
+#ifdef MODULE
+int init_module(void)
+{
+       int ret_val;
+
+       printk("Linux agpgart interface v%d.%d (c) Jeff Hartmann\n",
+              AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
+       ret_val = agp_backend_initialize();
+
+       if (ret_val != 0) {
+               return ret_val;
+       }
+       ret_val = agp_frontend_initialize();
+
+       if (ret_val != 0) {
+               agp_backend_cleanup();
+               return ret_val;
+       }
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       agp_frontend_cleanup();
+       agp_backend_cleanup();
+}
+
+#endif
diff --git a/drivers/char/agp/agp_backendP.h b/drivers/char/agp/agp_backendP.h
new file mode 100644 (file)
index 0000000..59beb02
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * AGPGART module version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight
+ * Copyright (C) 1999 Xi Graphics
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ */
+
+#ifndef _AGP_BACKEND_PRIV_H
+#define _AGP_BACKEND_PRIV_H 1
+
+enum aper_size_type {
+       U8_APER_SIZE,
+       U16_APER_SIZE,
+       U32_APER_SIZE,
+       FIXED_APER_SIZE
+};
+
+typedef struct _gatt_mask {
+       unsigned long mask;
+       u32 type;
+       /* totally device specific, for integrated chipsets that 
+        * might have different types of memory masks.  For other
+        * devices this will probably be ignored */
+} gatt_mask;
+
+typedef struct _aper_size_info_8 {
+       int size;
+       int num_entries;
+       int page_order;
+       u8 size_value;
+} aper_size_info_8;
+
+typedef struct _aper_size_info_16 {
+       int size;
+       int num_entries;
+       int page_order;
+       u16 size_value;
+} aper_size_info_16;
+
+typedef struct _aper_size_info_32 {
+       int size;
+       int num_entries;
+       int page_order;
+       u32 size_value;
+} aper_size_info_32;
+
+typedef struct _aper_size_info_fixed {
+       int size;
+       int num_entries;
+       int page_order;
+} aper_size_info_fixed;
+
+struct agp_bridge_data {
+       agp_version *version;
+       void *aperture_sizes;
+       void *previous_size;
+       void *current_size;
+       void *dev_private_data;
+       struct pci_dev *dev;
+       gatt_mask *masks;
+       unsigned long *gatt_table;
+       unsigned long *gatt_table_real;
+       unsigned long scratch_page;
+       unsigned long gart_bus_addr;
+       unsigned long gatt_bus_addr;
+       u32 mode;
+       enum chipset_type type;
+       enum aper_size_type size_type;
+       u32 *key_list;
+       atomic_t current_memory_agp;
+       atomic_t agp_in_use;
+       int max_memory_agp;     /* in number of pages */
+       int needs_scratch_page;
+       int aperture_size_idx;
+       int num_aperture_sizes;
+       int num_of_masks;
+       int capndx;
+
+       /* Links to driver specific functions */
+
+       int (*fetch_size) (void);       /* returns the index into the size table */
+       int (*configure) (void);
+       void (*agp_enable) (u32);
+       void (*cleanup) (void);
+       void (*tlb_flush) (agp_memory *);
+       unsigned long (*mask_memory) (unsigned long, int);
+       void (*cache_flush) (void);
+       int (*create_gatt_table) (void);
+       int (*free_gatt_table) (void);
+       int (*insert_memory) (agp_memory *, off_t, int);
+       int (*remove_memory) (agp_memory *, off_t, int);
+       agp_memory *(*alloc_by_type) (size_t, int);
+       void (*free_by_type) (agp_memory *);
+
+       /* Links to vendor/device specific setup functions */
+#ifdef AGP_BUILD_INTEL_GENERIC
+       void (*intel_generic_setup) (void);
+#endif
+#ifdef AGP_BUILD_INTEL_I810
+       void (*intel_i810_setup) (struct pci_dev *);
+#endif
+#ifdef AGP_BUILD_VIA_GENERIC
+       void (*via_generic_setup) (void);
+#endif
+#ifdef AGP_BUILD_SIS_GENERIC
+       void (*sis_generic_setup) (void);
+#endif
+#ifdef AGP_BUILD_AMD_IRONGATE
+       void (*amd_irongate_setup) (void);
+#endif
+#ifdef AGP_BUILD_ALI_M1541
+       void (*ali_generic_setup) (void);
+#endif
+};
+
+#define OUTREG32(mmap, addr, val)   *(volatile u32 *)(mmap + (addr)) = (val)
+#define OUTREG16(mmap, addr, val)   *(volatile u16 *)(mmap + (addr)) = (val)
+#define OUTREG8 (mmap, addr, val)   *(volatile u8 *) (mmap + (addr)) = (val)
+
+#define INREG32(mmap, addr)         *(volatile u32 *)(mmap + (addr))
+#define INREG16(mmap, addr)         *(volatile u16 *)(mmap + (addr))
+#define INREG8 (mmap, addr)         *(volatile u8 *) (mmap + (addr))
+
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
+
+#ifndef PCI_DEVICE_ID_VIA_82C691_0
+#define PCI_DEVICE_ID_VIA_82C691_0      0x0691
+#endif
+#ifndef PCI_DEVICE_ID_VIA_82C691_1
+#define PCI_DEVICE_ID_VIA_82C691_1      0x8691
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_0
+#define PCI_DEVICE_ID_INTEL_810_0       0x7120
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_DC100_0
+#define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_E_0
+#define PCI_DEVICE_ID_INTEL_810_E_0     0x7124
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_82443GX_0
+#define PCI_DEVICE_ID_INTEL_82443GX_0   0x71a0
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_1
+#define PCI_DEVICE_ID_INTEL_810_1       0x7121
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_DC100_1
+#define PCI_DEVICE_ID_INTEL_810_DC100_1 0x7123
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_810_E_1
+#define PCI_DEVICE_ID_INTEL_810_E_1     0x7125
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_82443GX_1
+#define PCI_DEVICE_ID_INTEL_82443GX_1   0x71a1
+#endif
+#ifndef PCI_DEVICE_ID_AMD_IRONGATE_0
+#define PCI_DEVICE_ID_AMD_IRONGATE_0    0x7006
+#endif
+#ifndef PCI_VENDOR_ID_AL
+#define PCI_VENDOR_ID_AL               0x10b9
+#endif
+#ifndef PCI_DEVICE_ID_AL_M1541_0
+#define PCI_DEVICE_ID_AL_M1541_0       0x1541
+#endif
+
+/* intel register */
+#define INTEL_APBASE    0x10
+#define INTEL_APSIZE    0xb4
+#define INTEL_ATTBASE   0xb8
+#define INTEL_AGPCTRL   0xb0
+#define INTEL_NBXCFG    0x50
+#define INTEL_ERRSTS    0x91
+
+/* intel i810 registers */
+#define I810_GMADDR 0x10
+#define I810_MMADDR 0x14
+#define I810_PTE_BASE          0x10000
+#define I810_PTE_MAIN_UNCACHED 0x00000000
+#define I810_PTE_LOCAL         0x00000002
+#define I810_PTE_VALID         0x00000001
+#define I810_SMRAM_MISCC       0x70
+#define I810_GFX_MEM_WIN_SIZE  0x00010000
+#define I810_GFX_MEM_WIN_32M   0x00010000
+#define I810_GMS               0x000000c0
+#define I810_GMS_DISABLE       0x00000000
+#define I810_PGETBL_CTL        0x2020
+#define I810_PGETBL_ENABLED    0x00000001
+#define I810_DRAM_CTL          0x3000
+#define I810_DRAM_ROW_0        0x00000001
+#define I810_DRAM_ROW_0_SDRAM  0x00000001
+
+/* VIA register */
+#define VIA_APBASE      0x10
+#define VIA_GARTCTRL    0x80
+#define VIA_APSIZE      0x84
+#define VIA_ATTBASE     0x88
+
+/* SiS registers */
+#define SIS_APBASE      0x10
+#define SIS_ATTBASE     0x90
+#define SIS_APSIZE      0x94
+#define SIS_TLBCNTRL    0x97
+#define SIS_TLBFLUSH    0x98
+
+/* AMD registers */
+#define AMD_APBASE      0x10
+#define AMD_MMBASE      0x14
+#define AMD_APSIZE      0xac
+#define AMD_MODECNTL    0xb0
+#define AMD_GARTENABLE  0x02   /* In mmio region (16-bit register) */
+#define AMD_ATTBASE     0x04   /* In mmio region (32-bit register) */
+#define AMD_TLBFLUSH    0x0c   /* In mmio region (32-bit register) */
+#define AMD_CACHEENTRY  0x10   /* In mmio region (32-bit register) */
+
+/* ALi registers */
+#define ALI_APBASE     0x10
+#define ALI_AGPCTRL    0xb8
+#define ALI_ATTBASE    0xbc
+#define ALI_TLBCTRL    0xc0
+
+#endif                         /* _AGP_BACKEND_PRIV_H */
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
new file mode 100644 (file)
index 0000000..97d40b1
--- /dev/null
@@ -0,0 +1,1087 @@
+/*
+ * AGPGART module frontend version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight
+ * Copyright (C) 1999 Xi Graphics
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/miscdevice.h>
+#include <linux/agp_backend.h>
+#include <linux/agpgart.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/mman.h>
+
+static struct agp_front_data agp_fe;
+
+static agp_memory *agp_find_mem_by_key(int key)
+{
+       agp_memory *curr;
+
+       if (agp_fe.current_controller == NULL) {
+               return NULL;
+       }
+       curr = agp_fe.current_controller->pool;
+
+       while (curr != NULL) {
+               if (curr->key == key) {
+                       return curr;
+               }
+               curr = curr->next;
+       }
+
+       return NULL;
+}
+
+static void agp_remove_from_pool(agp_memory * temp)
+{
+       agp_memory *prev;
+       agp_memory *next;
+
+       /* Check to see if this is even in the memory pool */
+
+       if (agp_find_mem_by_key(temp->key) != NULL) {
+               next = temp->next;
+               prev = temp->prev;
+
+               if (prev != NULL) {
+                       prev->next = next;
+                       if (next != NULL) {
+                               next->prev = prev;
+                       }
+               } else {
+                       /* This is the first item on the list */
+                       if (next != NULL) {
+                               next->prev = NULL;
+                       }
+                       agp_fe.current_controller->pool = next;
+               }
+       }
+}
+
+/*
+ * Routines for managing each client's segment list -
+ * These routines handle adding and removing segments
+ * to each auth'ed client.
+ */
+
+static agp_segment_priv *agp_find_seg_in_client(const agp_client * client,
+                                               unsigned long offset,
+                                           int size, pgprot_t page_prot)
+{
+       agp_segment_priv *seg;
+       int num_segments, pg_start, pg_count, i;
+
+       pg_start = offset / 4096;
+       pg_count = size / 4096;
+       seg = *(client->segments);
+       num_segments = client->num_segments;
+
+       for (i = 0; i < client->num_segments; i++) {
+               if ((seg[i].pg_start == pg_start) &&
+                   (seg[i].pg_count == pg_count) &&
+                   (pgprot_val(seg[i].prot) == pgprot_val(page_prot))) {
+                       return seg + i;
+               }
+       }
+
+       return NULL;
+}
+
+static void agp_remove_seg_from_client(agp_client * client)
+{
+       if (client->segments != NULL) {
+               if (*(client->segments) != NULL) {
+                       kfree(*(client->segments));
+               }
+               kfree(client->segments);
+       }
+}
+
+static void agp_add_seg_to_client(agp_client * client,
+                              agp_segment_priv ** seg, int num_segments)
+{
+       agp_segment_priv **prev_seg;
+
+       prev_seg = client->segments;
+
+       if (prev_seg != NULL) {
+               agp_remove_seg_from_client(client);
+       }
+       client->num_segments = num_segments;
+       client->segments = seg;
+}
+
+/* Originally taken from linux/mm/mmap.c from the array
+ * protection_map.
+ * The original really should be exported to modules, or 
+ * some routine which does the conversion for you 
+ */
+
+static const pgprot_t my_protect_map[16] =
+{
+       __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
+       __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
+};
+
+static pgprot_t agp_convert_mmap_flags(int prot)
+{
+#define _trans(x,bit1,bit2) \
+((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
+
+       unsigned long prot_bits;
+       pgprot_t temp;
+
+       prot_bits = _trans(prot, PROT_READ, VM_READ) |
+           _trans(prot, PROT_WRITE, VM_WRITE) |
+           _trans(prot, PROT_EXEC, VM_EXEC);
+
+       prot_bits |= VM_SHARED;
+
+       temp = my_protect_map[prot_bits & 0x0000000f];
+
+       return temp;
+}
+
+static int agp_create_segment(agp_client * client, agp_region * region)
+{
+       agp_segment_priv **ret_seg;
+       agp_segment_priv *seg;
+       agp_segment *user_seg;
+       int i;
+
+       seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL);
+       if (seg == NULL) {
+               kfree(region->seg_list);
+               return -ENOMEM;
+       }
+       memset(seg, 0, (sizeof(agp_segment_priv) * region->seg_count));
+       user_seg = region->seg_list;
+
+       for (i = 0; i < region->seg_count; i++) {
+               seg[i].pg_start = user_seg[i].pg_start;
+               seg[i].pg_count = user_seg[i].pg_count;
+               seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
+       }
+       ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
+       if (ret_seg == NULL) {
+               kfree(region->seg_list);
+               kfree(seg);
+               return -ENOMEM;
+       }
+       *ret_seg = seg;
+       kfree(region->seg_list);
+       agp_add_seg_to_client(client, ret_seg, region->seg_count);
+       return 0;
+}
+
+/* End - Routines for managing each client's segment list */
+
+/* This function must only be called when current_controller != NULL */
+static void agp_insert_into_pool(agp_memory * temp)
+{
+       agp_memory *prev;
+
+       prev = agp_fe.current_controller->pool;
+
+       if (prev != NULL) {
+               prev->prev = temp;
+               temp->next = prev;
+       }
+       agp_fe.current_controller->pool = temp;
+}
+
+
+/* File private list routines */
+
+agp_file_private *agp_find_private(pid_t pid)
+{
+       agp_file_private *curr;
+
+       curr = agp_fe.file_priv_list;
+
+       while (curr != NULL) {
+               if (curr->my_pid == pid) {
+                       return curr;
+               }
+               curr = curr->next;
+       }
+
+       return NULL;
+}
+
+void agp_insert_file_private(agp_file_private * priv)
+{
+       agp_file_private *prev;
+
+       prev = agp_fe.file_priv_list;
+
+       if (prev != NULL) {
+               prev->prev = priv;
+       }
+       priv->next = prev;
+       agp_fe.file_priv_list = priv;
+}
+
+void agp_remove_file_private(agp_file_private * priv)
+{
+       agp_file_private *next;
+       agp_file_private *prev;
+
+       next = priv->next;
+       prev = priv->prev;
+
+       if (prev != NULL) {
+               prev->next = next;
+
+               if (next != NULL) {
+                       next->prev = prev;
+               }
+       } else {
+               if (next != NULL) {
+                       next->prev = NULL;
+               }
+               agp_fe.file_priv_list = next;
+       }
+}
+
+/* End - File flag list routines */
+
+/* 
+ * Wrappers for agp_free_memory & agp_allocate_memory 
+ * These make sure that internal lists are kept updated.
+ */
+static void agp_free_memory_wrap(agp_memory * memory)
+{
+       agp_remove_from_pool(memory);
+       agp_free_memory(memory);
+}
+
+static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
+{
+       agp_memory *memory;
+
+       memory = agp_allocate_memory(pg_count, type);
+
+       if (memory == NULL) {
+               return NULL;
+       }
+       agp_insert_into_pool(memory);
+       return memory;
+}
+
+/* Routines for managing the list of controllers -
+ * These routines manage the current controller, and the list of
+ * controllers
+ */
+
+static agp_controller *agp_find_controller_by_pid(pid_t id)
+{
+       agp_controller *controller;
+
+       controller = agp_fe.controllers;
+
+       while (controller != NULL) {
+               if (controller->pid == id) {
+                       return controller;
+               }
+               controller = controller->next;
+       }
+
+       return NULL;
+}
+
+static agp_controller *agp_create_controller(pid_t id)
+{
+       agp_controller *controller;
+
+       controller = kmalloc(sizeof(agp_controller), GFP_KERNEL);
+
+       if (controller == NULL) {
+               return NULL;
+       }
+       memset(controller, 0, sizeof(agp_controller));
+       controller->pid = id;
+
+       return controller;
+}
+
+static int agp_insert_controller(agp_controller * controller)
+{
+       agp_controller *prev_controller;
+
+       prev_controller = agp_fe.controllers;
+       controller->next = prev_controller;
+
+       if (prev_controller != NULL) {
+               prev_controller->prev = controller;
+       }
+       agp_fe.controllers = controller;
+
+       return 0;
+}
+
+static void agp_remove_all_clients(agp_controller * controller)
+{
+       agp_client *client;
+       agp_client *temp;
+
+       client = controller->clients;
+
+       while (client) {
+               agp_file_private *priv;
+
+               temp = client;
+               agp_remove_seg_from_client(temp);
+               priv = agp_find_private(temp->pid);
+
+               if (priv != NULL) {
+                       clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
+                       clear_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
+               }
+               client = client->next;
+               kfree(temp);
+       }
+}
+
+static void agp_remove_all_memory(agp_controller * controller)
+{
+       agp_memory *memory;
+       agp_memory *temp;
+
+       memory = controller->pool;
+
+       while (memory) {
+               temp = memory;
+               memory = memory->next;
+               agp_free_memory_wrap(temp);
+       }
+}
+
+static int agp_remove_controller(agp_controller * controller)
+{
+       agp_controller *prev_controller;
+       agp_controller *next_controller;
+
+       prev_controller = controller->prev;
+       next_controller = controller->next;
+
+       if (prev_controller != NULL) {
+               prev_controller->next = next_controller;
+               if (next_controller != NULL) {
+                       next_controller->prev = prev_controller;
+               }
+       } else {
+               if (next_controller != NULL) {
+                       next_controller->prev = NULL;
+               }
+               agp_fe.controllers = next_controller;
+       }
+
+       agp_remove_all_memory(controller);
+       agp_remove_all_clients(controller);
+
+       if (agp_fe.current_controller == controller) {
+               agp_fe.current_controller = NULL;
+               agp_fe.backend_acquired = FALSE;
+               agp_backend_release();
+       }
+       kfree(controller);
+       return 0;
+}
+
+static void agp_controller_make_current(agp_controller * controller)
+{
+       agp_client *clients;
+
+       clients = controller->clients;
+
+       while (clients != NULL) {
+               agp_file_private *priv;
+
+               priv = agp_find_private(clients->pid);
+
+               if (priv != NULL) {
+                       set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
+                       set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
+               }
+               clients = clients->next;
+       }
+
+       agp_fe.current_controller = controller;
+}
+
+static void agp_controller_release_current(agp_controller * controller,
+                                     agp_file_private * controller_priv)
+{
+       agp_client *clients;
+
+       clear_bit(AGP_FF_IS_VALID, &(controller_priv->access_flags));
+       clients = controller->clients;
+
+       while (clients != NULL) {
+               agp_file_private *priv;
+
+               priv = agp_find_private(clients->pid);
+
+               if (priv != NULL) {
+                       clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
+               }
+               clients = clients->next;
+       }
+
+       agp_fe.current_controller = NULL;
+       agp_fe.used_by_controller = FALSE;
+       agp_backend_release();
+}
+
+/* 
+ * Routines for managing client lists -
+ * These routines are for managing the list of auth'ed clients.
+ */
+
+static agp_client *agp_find_client_in_controller(agp_controller * controller,
+                                                pid_t id)
+{
+       agp_client *client;
+
+       if (controller == NULL) {
+               return NULL;
+       }
+       client = controller->clients;
+
+       while (client != NULL) {
+               if (client->pid == id) {
+                       return client;
+               }
+               client = client->next;
+       }
+
+       return NULL;
+}
+
+static agp_controller *agp_find_controller_for_client(pid_t id)
+{
+       agp_controller *controller;
+
+       controller = agp_fe.controllers;
+
+       while (controller != NULL) {
+               if ((agp_find_client_in_controller(controller, id)) != NULL) {
+                       return controller;
+               }
+               controller = controller->next;
+       }
+
+       return NULL;
+}
+
+static agp_client *agp_find_client_by_pid(pid_t id)
+{
+       agp_client *temp;
+
+       if (agp_fe.current_controller == NULL) {
+               return NULL;
+       }
+       temp = agp_find_client_in_controller(agp_fe.current_controller, id);
+       return temp;
+}
+
+static void agp_insert_client(agp_client * client)
+{
+       agp_client *prev_client;
+
+       prev_client = agp_fe.current_controller->clients;
+       client->next = prev_client;
+
+       if (prev_client != NULL) {
+               prev_client->prev = client;
+       }
+       agp_fe.current_controller->clients = client;
+       agp_fe.current_controller->num_clients++;
+}
+
+static agp_client *agp_create_client(pid_t id)
+{
+       agp_client *new_client;
+
+       new_client = kmalloc(sizeof(agp_client), GFP_KERNEL);
+
+       if (new_client == NULL) {
+               return NULL;
+       }
+       memset(new_client, 0, sizeof(agp_client));
+       new_client->pid = id;
+       agp_insert_client(new_client);
+       return new_client;
+}
+
+static int agp_remove_client(pid_t id)
+{
+       agp_client *client;
+       agp_client *prev_client;
+       agp_client *next_client;
+       agp_controller *controller;
+
+       controller = agp_find_controller_for_client(id);
+
+       if (controller == NULL) {
+               return -EINVAL;
+       }
+       client = agp_find_client_in_controller(controller, id);
+
+       if (client == NULL) {
+               return -EINVAL;
+       }
+       prev_client = client->prev;
+       next_client = client->next;
+
+       if (prev_client != NULL) {
+               prev_client->next = next_client;
+               if (next_client != NULL) {
+                       next_client->prev = prev_client;
+               }
+       } else {
+               if (next_client != NULL) {
+                       next_client->prev = NULL;
+               }
+               controller->clients = next_client;
+       }
+
+       controller->num_clients--;
+       agp_remove_seg_from_client(client);
+       kfree(client);
+       return 0;
+}
+
+/* End - Routines for managing client lists */
+
+/* File Operations */
+
+static int agp_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       int size;
+       int current_size;
+       unsigned long offset;
+       agp_client *client;
+       agp_file_private *priv = (agp_file_private *) file->private_data;
+       agp_kern_info kerninfo;
+
+       AGP_LOCK();
+
+       if (agp_fe.backend_acquired != TRUE) {
+               AGP_UNLOCK();
+               return -EPERM;
+       }
+       if (!(test_bit(AGP_FF_IS_VALID, &(priv->access_flags)))) {
+               AGP_UNLOCK();
+               return -EPERM;
+       }
+       agp_copy_info(&kerninfo);
+       size = vma->vm_end - vma->vm_start;
+       current_size = kerninfo.aper_size;
+       current_size = current_size * 0x100000;
+       offset = vma->vm_pgoff << PAGE_SHIFT;
+
+       if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
+               if ((size + offset) > current_size) {
+                       AGP_UNLOCK();
+                       return -EINVAL;
+               }
+               client = agp_find_client_by_pid(current->pid);
+
+               if (client == NULL) {
+                       AGP_UNLOCK();
+                       return -EPERM;
+               }
+               if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) {
+                       AGP_UNLOCK();
+                       return -EINVAL;
+               }
+               if (remap_page_range(vma->vm_start, (kerninfo.aper_base + offset),
+                                    size, vma->vm_page_prot)) {
+                       AGP_UNLOCK();
+                       return -EAGAIN;
+               }
+               AGP_UNLOCK();
+               return 0;
+       }
+       if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
+               if (size != current_size) {
+                       AGP_UNLOCK();
+                       return -EINVAL;
+               }
+               if (remap_page_range(vma->vm_start, kerninfo.aper_base,
+                                    size, vma->vm_page_prot)) {
+                       AGP_UNLOCK();
+                       return -EAGAIN;
+               }
+               AGP_UNLOCK();
+               return 0;
+       }
+       AGP_UNLOCK();
+       return -EPERM;
+}
+
+static int agp_release(struct inode *inode, struct file *file)
+{
+       agp_file_private *priv = (agp_file_private *) file->private_data;
+
+       AGP_LOCK();
+
+       if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
+               agp_controller *controller;
+
+               controller = agp_find_controller_by_pid(priv->my_pid);
+
+               if (controller != NULL) {
+                       if (controller == agp_fe.current_controller) {
+                               agp_controller_release_current(controller, priv);
+                       }
+                       agp_remove_controller(controller);
+               }
+       }
+       if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
+               agp_remove_client(priv->my_pid);
+       }
+       agp_remove_file_private(priv);
+       kfree(priv);
+       MOD_DEC_USE_COUNT;
+       AGP_UNLOCK();
+       return 0;
+}
+
+static int agp_open(struct inode *inode, struct file *file)
+{
+       int minor = MINOR(inode->i_rdev);
+       agp_file_private *priv;
+       agp_client *client;
+
+       AGP_LOCK();
+
+       if (minor != AGPGART_MINOR) {
+               AGP_UNLOCK();
+               return -ENXIO;
+       }
+       priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL);
+
+       if (priv == NULL) {
+               AGP_UNLOCK();
+               return -ENOMEM;
+       }
+       memset(priv, 0, sizeof(agp_file_private));
+       set_bit(AGP_FF_ALLOW_CLIENT, &(priv->access_flags));
+       priv->my_pid = current->pid;
+
+       if ((current->uid == 0) || (current->suid == 0)) {
+               /* Root priv, can be controller */
+               set_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags));
+       }
+       client = agp_find_client_by_pid(current->pid);
+
+       if (client != NULL) {
+               set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
+               set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
+       }
+       file->private_data = (void *) priv;
+       agp_insert_file_private(priv);
+       MOD_INC_USE_COUNT;
+       AGP_UNLOCK();
+       return 0;
+}
+
+
+static long long agp_lseek(struct file *file, long long offset, int origin)
+{
+       return -ESPIPE;
+}
+
+static ssize_t agp_read(struct file *file, char *buf,
+                       size_t count, loff_t * ppos)
+{
+       return -EINVAL;
+}
+
+static ssize_t agp_write(struct file *file, const char *buf,
+                        size_t count, loff_t * ppos)
+{
+       return -EINVAL;
+}
+
+static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_info userinfo;
+       agp_kern_info kerninfo;
+
+       agp_copy_info(&kerninfo);
+
+       userinfo.version.major = kerninfo.version.major;
+       userinfo.version.minor = kerninfo.version.minor;
+       userinfo.bridge_id = kerninfo.device->vendor | (kerninfo.device->device << 16);
+       userinfo.agp_mode = kerninfo.mode;
+       userinfo.aper_base = kerninfo.aper_base;
+       userinfo.aper_size = kerninfo.aper_size;
+       userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
+       userinfo.pg_used = kerninfo.current_memory;
+
+       if (copy_to_user((void *) arg, &userinfo, sizeof(agp_info))) {
+               return -EFAULT;
+       }
+       return 0;
+}
+
+static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_controller *controller;
+       if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags)))) {
+               return -EPERM;
+       }
+       if (agp_fe.current_controller != NULL) {
+               return -EBUSY;
+       }
+       if ((agp_backend_acquire()) == 0) {
+               agp_fe.backend_acquired = TRUE;
+       } else {
+               return -EBUSY;
+       }
+
+       controller = agp_find_controller_by_pid(priv->my_pid);
+
+       if (controller != NULL) {
+               agp_controller_make_current(controller);
+       } else {
+               controller = agp_create_controller(priv->my_pid);
+
+               if (controller == NULL) {
+                       agp_fe.backend_acquired = FALSE;
+                       agp_backend_release();
+                       return -ENOMEM;
+               }
+               agp_insert_controller(controller);
+               agp_controller_make_current(controller);
+       }
+
+       set_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags));
+       set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
+       return 0;
+}
+
+static int agpioc_release_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_controller_release_current(agp_fe.current_controller, priv);
+       return 0;
+}
+
+static int agpioc_setup_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_setup mode;
+
+       if (copy_from_user(&mode, (void *) arg, sizeof(agp_setup))) {
+               return -EFAULT;
+       }
+       agp_enable(mode.agp_mode);
+       return 0;
+}
+
+static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_region reserve;
+       agp_client *client;
+       agp_file_private *client_priv;
+
+
+       if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) {
+               return -EFAULT;
+       }
+       client = agp_find_client_by_pid(reserve.pid);
+
+       if (reserve.seg_count == 0) {
+               /* remove a client */
+               client_priv = agp_find_private(reserve.pid);
+
+               if (client_priv != NULL) {
+                       set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
+                       set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
+               }
+               if (client == NULL) {
+                       /* client is already removed */
+                       return 0;
+               }
+               return agp_remove_client(reserve.pid);
+       } else {
+               agp_segment *segment;
+
+               segment = kmalloc((sizeof(agp_segment) * reserve.seg_count), GFP_KERNEL);
+
+               if (segment == NULL) {
+                       return -ENOMEM;
+               }
+               if (copy_from_user(segment, (void *) reserve.seg_list, GFP_KERNEL)) {
+                       kfree(segment);
+                       return -EFAULT;
+               }
+               reserve.seg_list = segment;
+
+               if (client == NULL) {
+                       /* Create the client and add the segment */
+                       client = agp_create_client(reserve.pid);
+
+                       if (client == NULL) {
+                               kfree(segment);
+                               return -ENOMEM;
+                       }
+                       client_priv = agp_find_private(reserve.pid);
+
+                       if (client_priv != NULL) {
+                               set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
+                               set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
+                       }
+                       return agp_create_segment(client, &reserve);
+               } else {
+                       return agp_create_segment(client, &reserve);
+               }
+       }
+       /* Will never really happen */
+       return -EINVAL;
+}
+
+static int agpioc_protect_wrap(agp_file_private * priv, unsigned long arg)
+{
+       /* This function is not currently implemented */
+       return -EINVAL;
+}
+
+static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_memory *memory;
+       agp_allocate alloc;
+
+       if (copy_from_user(&alloc, (void *) arg, sizeof(agp_allocate))) {
+               return -EFAULT;
+       }
+       memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
+
+       if (memory == NULL) {
+               return -ENOMEM;
+       }
+       alloc.key = memory->key;
+
+       if (copy_to_user((void *) arg, &alloc, sizeof(agp_allocate))) {
+               agp_free_memory_wrap(memory);
+               return -EFAULT;
+       }
+       return 0;
+}
+
+static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_memory *memory;
+
+       memory = agp_find_mem_by_key((int) arg);
+
+       if (memory == NULL) {
+               return -EINVAL;
+       }
+       agp_free_memory_wrap(memory);
+       return 0;
+}
+
+static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_bind bind_info;
+       agp_memory *memory;
+
+       if (copy_from_user(&bind_info, (void *) arg, sizeof(agp_bind))) {
+               return -EFAULT;
+       }
+       memory = agp_find_mem_by_key(bind_info.key);
+
+       if (memory == NULL) {
+               return -EINVAL;
+       }
+       return agp_bind_memory(memory, bind_info.pg_start);
+}
+
+static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg)
+{
+       agp_memory *memory;
+       agp_unbind unbind;
+
+       if (copy_from_user(&unbind, (void *) arg, sizeof(agp_unbind))) {
+               return -EFAULT;
+       }
+       memory = agp_find_mem_by_key(unbind.key);
+
+       if (memory == NULL) {
+               return -EINVAL;
+       }
+       return agp_unbind_memory(memory);
+}
+
+static int agp_ioctl(struct inode *inode, struct file *file,
+                    unsigned int cmd, unsigned long arg)
+{
+       agp_file_private *curr_priv = (agp_file_private *) file->private_data;
+       int ret_val;
+
+       AGP_LOCK();
+
+       if ((agp_fe.current_controller == NULL) &&
+           (cmd != AGPIOC_ACQUIRE)) {
+               return -EINVAL;
+       }
+       if ((agp_fe.backend_acquired != TRUE) &&
+           (cmd != AGPIOC_ACQUIRE)) {
+               return -EBUSY;
+       }
+       if (cmd != AGPIOC_ACQUIRE) {
+               if (!(test_bit(AGP_FF_IS_CONTROLLER, &(curr_priv->access_flags)))) {
+                       return -EPERM;
+               }
+               /* Use the original pid of the controller, in case it's threaded */
+
+               if (agp_fe.current_controller->pid != curr_priv->my_pid) {
+                       return -EBUSY;
+               }
+       }
+       switch (cmd) {
+       case AGPIOC_INFO:
+               {
+                       ret_val = agpioc_info_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_ACQUIRE:
+               {
+                       ret_val = agpioc_acquire_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_RELEASE:
+               {
+                       ret_val = agpioc_release_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_SETUP:
+               {
+                       ret_val = agpioc_setup_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_RESERVE:
+               {
+                       ret_val = agpioc_reserve_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_PROTECT:
+               {
+                       ret_val = agpioc_protect_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_ALLOCATE:
+               {
+                       ret_val = agpioc_allocate_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_DEALLOCATE:
+               {
+                       ret_val = agpioc_deallocate_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_BIND:
+               {
+                       ret_val = agpioc_bind_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       case AGPIOC_UNBIND:
+               {
+                       ret_val = agpioc_unbind_wrap(curr_priv, arg);
+                       AGP_UNLOCK();
+                       return ret_val;
+               }
+       }
+
+       AGP_UNLOCK();
+       return -ENOTTY;
+}
+
+static struct file_operations agp_fops =
+{
+       agp_lseek,
+       agp_read,
+       agp_write,
+       NULL,
+       NULL,
+       agp_ioctl,
+       agp_mmap,
+       agp_open,
+       NULL,
+       agp_release
+};
+
+static struct miscdevice agp_miscdev =
+{
+       AGPGART_MINOR,
+       "agpgart",
+       &agp_fops
+};
+
+int agp_frontend_initialize(void)
+{
+       memset(&agp_fe, 0, sizeof(struct agp_front_data));
+       AGP_LOCK_INIT();
+
+       if (misc_register(&agp_miscdev)) {
+               printk("agpgart: unable to get minor: %d\n", AGPGART_MINOR);
+               return -EIO;
+       }
+       return 0;
+}
+
+void agp_frontend_cleanup(void)
+{
+       return;
+}
index 780c4fb69c1948e9b84e3cd1dec1c0481096ead8..a71d6dde98acb183702a72ade533f06bb8fd14e3 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define __NO_VERSION__
+#include <linux/config.h>
 #include "drmP.h"
 #include "linux/un.h"
 
index 966e6e05a60cd61905ef64c52bfddd038071d062..5e9d098696f6f476cb546e58278078f2520fc934 100644 (file)
@@ -33,6 +33,7 @@
 #define _DRM_P_H_
 
 #ifdef __KERNEL__
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
index 0ae7814ccad729c4f07cf9f880cdd934ca69c230..2a966cab1f155a202dd7057d8f0eb2569b1543f5 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define EXPORT_SYMTAB
+#include <linux/config.h>
 #include "drmP.h"
 #include "gamma_drv.h"
 EXPORT_SYMBOL(gamma_init);
index a555e9bc808b73149a91c8a2281c12fc23184cd2..c5913a08ef781cfef4b566bd827b6186f908d338 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #define EXPORT_SYMTAB
+#include <linux/config.h>
 #include "drmP.h"
 #include "tdfx_drv.h"
 EXPORT_SYMBOL(tdfx_init);
index ccaa550a972023038e1f7bde03d92fc22772072f..09030e6946c42b7ed896e8c8478b61fe65e8a2fd 100644 (file)
@@ -248,17 +248,14 @@ if [ "$CONFIG_NET_RADIO" = "y" ]; then
    tristate '  AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
    tristate '  Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN
    tristate '  Aironet 4500/4800 series adapters' CONFIG_AIRONET4500
-   if [ ! "$CONFIG_AIRONET4500" = "n" ]; then
-          dep_tristate '   Aironet 4500/4800 ISA/PCI/PNP/365 support ' CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
-          if [ ! "$CONFIG_AIRONET4500_NONCS" = "n" ]; then
-                  bool '     Aironet 4500/4800 PNP support ' CONFIG_AIRONET4500_PNP $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
-                  bool '     Aironet 4500/4800 PCI support ' CONFIG_AIRONET4500_PCI  $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
-                  bool '     Aironet 4500/4800 ISA broken support ' CONFIG_AIRONET4500_ISA  $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500 $CONFIG_EXPERIMENTAL
-                  bool '     Aironet 4500/4800 I365 broken support ' CONFIG_AIRONET4500_I365   $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500 $CONFIG_EXPERIMENTAL
-          fi
-          dep_tristate '   Aironet 4500/4800 PCMCIA support ' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA
-          dep_tristate '   Aironet 4500/4800 PROC interface ' CONFIG_AIRONET4500_PROC $CONFIG_AIRONET4500 m
+   dep_tristate '   Aironet 4500/4800 ISA/PCI/PNP/365 support ' CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
+   if [ "$CONFIG_AIRONET4500" != "n" -a "$CONFIG_AIRONET4500_NONCS" != "n" ]; then
+      bool '     Aironet 4500/4800 PNP support ' CONFIG_AIRONET4500_PNP
+      dep_bool '     Aironet 4500/4800 PCI support ' CONFIG_AIRONET4500_PCI $CONFIG_PCI
+      dep_bool '     Aironet 4500/4800 ISA broken support (EXPERIMENTAL)' CONFIG_AIRONET4500_ISA $CONFIG_EXPERIMENTAL
+      dep_bool '     Aironet 4500/4800 I365 broken support (EXPERIMENTAL)' CONFIG_AIRONET4500_I365 $CONFIG_EXPERIMENTAL
    fi
+   dep_tristate '   Aironet 4500/4800 PROC interface ' CONFIG_AIRONET4500_PROC $CONFIG_AIRONET4500 m
 fi
 
 endmenu
index 9ae10017837d4dcd31180ca8153fac64af0a11c0..933ce485e2349943656ee46b6985727b5736109a 100644 (file)
@@ -15,7 +15,6 @@
 #define        AIRONET4500_H
 // redefined to avoid PCMCIA includes
 
-#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
index fe7b04a11f1bbd5af147981ef0161cfaf41b3e6f..1725f4aec54b4b065189ef5c51d2003614023f61 100644 (file)
@@ -29,7 +29,6 @@ static const char *awc_version =
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/timer.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index 2462d9d2a213dee0f1c46dc6baf54efc20faf9bd..4461ad2fba236e6db0a93eecfe16ff2150e20161 100644 (file)
@@ -10,7 +10,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
index 58aec79ffa7b3b942be19c2af2bd4d26229db3f5..756f7266f6f28119d75b9be08d0554c89b3bcc12 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/timer.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index 99163c732502e35b82af4f00f5a2a8e45978863b..f1fb95dd67a33bd172c6ea4842a6ad1115d7d49c 100644 (file)
@@ -10,7 +10,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 
index c392d80a9bc86498d3d9a7bfd8caa8bdaf676a9c..8582587c17d222d2e91a93b06529e961f4116ea7 100644 (file)
@@ -437,9 +437,9 @@ int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options
           There are two HP versions, check the BIOS for the configuration port.
           This method provided by L. Julliard, Laurent_Julliard@grenoble.hp.com.
           */
-       if (readw(0x000f0102) == 0x5048)  {
+       if (isa_readw(0x000f0102) == 0x5048)  {
                static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
-               int hp_port = (readl(0x000f00f1) & 1)  ? 0x499 : 0x99;
+               int hp_port = (isa_readl(0x000f00f1) & 1)  ? 0x499 : 0x99;
                /* We can have boards other than the built-in!  Verify this is on-board. */
                if ((inb(hp_port) & 0xc0) == 0x80
                        && ioaddr_table[inb(hp_port) & 3] == ioaddr)
index f97f41b118d3486b511f53f72c285972aac77219..3dbb9923fc3b81e559aa266742e8bc52dc06e5ff 100644 (file)
@@ -14,7 +14,6 @@ static const char *awc_version =
 "aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 //#include <pcmcia/config.h>
 
@@ -29,7 +28,6 @@ static const char *awc_version =
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/timer.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
diff --git a/drivers/pci/Config.in b/drivers/pci/Config.in
new file mode 100644 (file)
index 0000000..de54064
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# PCI configuration
+#
+
+if [ "$CONFIG_PCI" = "y" ]; then
+   bool 'PCI device name database' CONFIG_PCI_NAMES
+fi
index 2913461938ad919650a28aaf75a46df48c877cfa..2502f7124989248be9304dfbab399718a431d20c 100644 (file)
@@ -33,10 +33,10 @@ endif
 
 include $(TOPDIR)/Rules.make
 
-names.o: names.c devlist.h
+names.o: names.c devlist.h classlist.h
 
-devlist.h: pci.ids gen-devlist
-       ./gen-devlist <pci.ids >devlist.h
+devlist.h classlist.h: pci.ids gen-devlist
+       ./gen-devlist <pci.ids
 
 gen-devlist: gen-devlist.c
        $(HOSTCC) $(HOSTCFLAGS) -o gen-devlist gen-devlist.c
index 3d4c364151cc40897b4584d7bcfbe84e139d973a..9337d80b0cb8d2d6b12f1373563f806ec1425932 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     Generate devlist.h from the PCI ID file.
+ *     Generate devlist.h and classlist.h from the PCI ID file.
  *
  *     (c) 1999 Martin Mares <mj@suse.cz>
  */
@@ -8,13 +8,13 @@
 #include <string.h>
 
 static void
-pq(char *c)
+pq(FILE *f, char *c)
 {
        while (*c) {
                if (*c == '"')
-                       printf("\\\"");
+                       fprintf(f, "\\\"");
                else
-                       putchar(*c);
+                       fputc(*c, f);
                c++;
        }
 }
@@ -24,6 +24,15 @@ main(void)
 {
        char line[1024], *c, vend[8];
        int vendors = 0;
+       int mode = 0;
+       FILE *devf, *clsf;
+
+       devf = fopen("devlist.h", "w");
+       clsf = fopen("classlist.h", "w");
+       if (!devf || !clsf) {
+               fprintf(stderr, "Cannot create output file!\n");
+               return 1;
+       }
 
        while (fgets(line, sizeof(line)-1, stdin)) {
                if ((c = strchr(line, '\n')))
@@ -31,36 +40,65 @@ main(void)
                if (!line[0] || line[0] == '#')
                        continue;
                if (line[1] == ' ') {
-                       vend[0] = 0;
-                       continue;
+                       if (line[0] == 'C' && strlen(line) > 4 && line[4] == ' ') {
+                               vend[0] = line[2];
+                               vend[1] = line[3];
+                               vend[2] = 0;
+                               mode = 2;
+                       } else goto err;
                }
-               if (line[0] == '\t') {
-                       if (vend[0] && strlen(line) > 5 && line[5] == ' ') {
-                               c = line + 5;
-                               while (*c == ' ')
-                                       *c++ = 0;
-                               printf("\tDEVICE(%s,%s,\"", vend, line+1);
-                               pq(c);
-                               puts("\")");
+               else if (line[0] == '\t') {
+                       if (line[1] == '\t')
+                               continue;
+                       switch (mode) {
+                       case 1:
+                               if (strlen(line) > 5 && line[5] == ' ') {
+                                       c = line + 5;
+                                       while (*c == ' ')
+                                               *c++ = 0;
+                                       fprintf(devf, "\tDEVICE(%s,%s,\"", vend, line+1);
+                                       pq(devf, c);
+                                       fputs("\")\n", devf);
+                               } else goto err;
+                               break;
+                       case 2:
+                               if (strlen(line) > 3 && line[3] == ' ') {
+                                       c = line + 3;
+                                       while (*c == ' ')
+                                               *c++ = 0;
+                                       fprintf(clsf, "CLASS(%s%s, \"%s\")\n", vend, line+1, c);
+                               } else goto err;
+                               break;
+                       default:
+                               goto err;
                        }
                } else if (strlen(line) > 4 && line[4] == ' ') {
                        c = line + 4;
                        while (*c == ' ')
                                *c++ = 0;
                        if (vendors)
-                               puts("ENDVENDOR()\n");
+                               fputs("ENDVENDOR()\n\n", devf);
                        vendors++;
                        strcpy(vend, line);
-                       printf("VENDOR(%s,\"", vend);
-                       pq(c);
-                       puts("\")");
+                       fprintf(devf, "VENDOR(%s,\"", vend);
+                       pq(devf, c);
+                       fputs("\")\n", devf);
+                       mode = 1;
+               } else {
+               err:
+                       fprintf(stderr, "Syntax error in mode %d: %s\n", mode, line);
+                       return 1;
                }
        }
-       puts("ENDVENDOR()\n\
+       fputs("ENDVENDOR()\n\
 \n\
 #undef VENDOR\n\
 #undef DEVICE\n\
-#undef ENDVENDOR");
+#undef ENDVENDOR\n", devf);
+       fputs("\n#undef CLASS", clsf);
+
+       fclose(devf);
+       fclose(clsf);
 
        return 0;
 }
index 81dafad61c96585de257eccd4ec5550dc47459ea..ec85e07a8d7c2a3a6fe5c8ba2b5a979e5625947e 100644 (file)
@@ -1,9 +1,7 @@
 /*
- *     $Id: oldproc.c,v 1.24 1998/10/11 15:13:04 mj Exp $
+ *     PCI Class and Device Name Tables
  *
- *     Backward-compatible procfs interface for PCI.
- *
- *     Copyright 1993, 1994, 1995, 1997 Drew Eckhardt, Frederic Potter,
+ *     Copyright 1993--1999 Drew Eckhardt, Frederic Potter,
  *     David Mosberger-Tang, Martin Mares
  */
 
@@ -12,6 +10,8 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 
+#ifdef CONFIG_PCI_NAMES
+
 struct pci_device_info {
        unsigned short device;
        unsigned short seen;
@@ -92,3 +92,43 @@ void __init pci_name_device(struct pci_dev *dev)
                }
        }
 }
+
+/*
+ *  Class names. Not in .init section as they are needed in runtime.
+ */
+
+static u16 pci_class_numbers[] = {
+#define CLASS(x,y) 0x##x,
+#include "classlist.h"
+};
+
+static char *pci_class_names[] = {
+#define CLASS(x,y) y,
+#include "classlist.h"
+};
+
+char *
+pci_class_name(u32 class)
+{
+       int i;
+
+       for(i=0; i<sizeof(pci_class_numbers)/sizeof(pci_class_numbers[0]); i++)
+               if (pci_class_numbers[i] == class)
+                       return pci_class_names[i];
+       return NULL;
+}
+
+#else
+
+void __init pci_name_device(struct pci_dev *dev)
+{
+       sprintf(dev->name, "PCI device %04x:%04x", dev->vendor, dev->device);
+}
+
+char *
+pci_class_name(u32 class)
+{
+       return NULL;
+}
+
+#endif
index 28180181afc996d4c6a84b9c218667696539bdbc..05dc22cd1be795fd2cf5ab941120215a7cdf44b9 100644 (file)
@@ -491,13 +491,16 @@ static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
                        pci_read_config_word(dev, PCI_CB_SUBSYSTEM_ID, &dev->subsystem_device);
                        break;
                default:                                    /* unknown header */
-               bad:
                        printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n",
                                dev->slot_name, hdr_type);
                        continue;
+               bad:
+                       printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n",
+                              dev->slot_name, class, hdr_type);
+                       dev->class = PCI_CLASS_NOT_DEFINED;
                }
 
-               DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
+               DBG("PCI: %02x:%02x [%04x/%04x] %06x %02x\n", bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
 
                /*
                 * Put it into the global PCI device chain. It's used to
index 6c8fa8c4269b9e3cba509c3119c1fdd3314d80c9..df51939e521fb96f01359434965951cebb9a95c0 100644 (file)
@@ -4,7 +4,7 @@
 #      Maintained by Martin Mares <pci-ids@ucw.cz>
 #      If you have any new entries, send them to the maintainer.
 #
-#      $Id: pci.ids,v 1.41 1999/10/30 09:25:10 mj Exp $
+#      $Id: pci.ids,v 1.43 1999/12/04 12:32:55 mj Exp $
 #
 
 # Vendors, devices and subsystems. Please keep sorted.
                1113 1207  EN-1207-TX Fast Ethernet
                1109 2400  ANA-6944A/TX Fast Ethernet
                1186 1100  DFE-500TX Fast Ethernet
+               1186 1112  DFE-570TX Fast Ethernet
                1282 9100  AEF-380TXD Fast Ethernet
                2646 0001  KNE100TX Fast Ethernet
        000a  21230 Video Codec
                1092 0157  FIRE GL 1000 PRO
                1097 3d01  Jeronimo Pro
                3d3d 0100  Reference Permedia 2 3D
-       8000  LYNX FireWire Host Controller
+       8000  PCILynx/PCILynx2 IEEE 1394 Link Layer Controller
+               e4bf 1010 CF1-1-SNARE
+               e4bf 1020 CF1-2-SNARE 
        8009  OHCI Compliant FireWire Controller
        8019  TSB12LV23 OHCI Compliant IEEE-1394 Controller
+               e4bf 1010 CF2-1-CYMBAL
        a001  TDC1570
        a100  TDC1561
        ac10  PCI1050
        fe00  FireWire Host Controller
        fe03  12C01A FireWire Host Controller
 104d  Sony Corporation
+       8039  CXD3222 iLINK Controller
 104e  Oak Technology, Inc
        0017  OTI-64017
        0107  OTI-107 [Spitfire]
        1683  IGA-1683
        2000  CyberPro 2000
        2010  CyberPro 2000A
+       5000  CyberPro 5000
+       5050  CyberPro 5050
 10eb  Artists Graphics
        0101  3GA
        8111  Twist3 Frame Grabber
 112e  Infomedia Microelectronics Inc.
 112f  Imaging Technology Inc
        0000  MVC IC-PCI
-       0001  Video frame grabber/processor
+       0001  MVC IM-PCI Video frame grabber/processor
 1130  Computervision
 1131  Philips Semiconductors
        7145  SAA7145
 1280  Photoscript Group Ltd.
 1281  Yokogawa Electric Corporation
 1282  Davicom Semiconductor, Inc.
+       9102  Ethernet 100/10 MBit
 1283  Integrated Technology Express, Inc.
        673a  IT8330G
        8330  IT8330G
 12b8  Korg
 12b9  US Robotics/3Com
        1006  WinModem
+       1008  56K FaxModem Model 5610
 12ba  PMC Sierra
 12bb  Nippon Unisoft Corporation
 12bc  Array Microsystems
 12c4  Connect Tech Inc
 12c5  Picture Elements Incorporated
        0081  PCIVST [Grayscale Thresholding Engine]
+       0086  THR2 Thresholder
 12c6  Mitani Corporation
 12c7  Dialogic Corp
 12c8  G Force Co, Ltd
 131d  Sysmic, Inc.
 131e  Xinex Networks Inc
 131f  Siig Inc
+       1000  CyberSerial (1-port) 16550
+       1001  CyberSerial (1-port) 16650
+       1002  CyberSerial (1-port) 16850
        1010  Duet 1S(16550)+1P
        1011  Duet 1S(16650)+1P
        1012  Duet 1S(16850)+1P
        1020  CyberParallel (1-port)
        1021  CyberParallel (2-port)
+       1030  CyberSerial (2-port) 16550
+       1031  CyberSerial (2-port) 16650
+       1032  CyberSerial (2-port) 16850
        1034  Trio 2S(16550)+1P
        1035  Trio 2S(16650)+1P
        1036  Trio 2S(16850)+1P
+       1050  CyberSerial (4-port) 16550
+       1051  CyberSerial (4-port) 16650
+       1052  CyberSerial (4-port) 16850
+       2000  CyberSerial (1-port) 16550
+       2001  CyberSerial (1-port) 16650
+       2002  CyberSerial (1-port) 16850
        2010  Duet 1S(16550)+1P
        2011  Duet 1S(16650)+1P
        2012  Duet 1S(16850)+1P
        2020  CyberParallel (1-port)
        2021  CyberParallel (2-port)
+       2030  CyberSerial (2-port) 16550
+       2031  CyberSerial (2-port) 16650
+       2032  CyberSerial (2-port) 16850
        2040  Trio 1S(16550)+2P
        2041  Trio 1S(16650)+2P
        2042  Trio 1S(16850)+2P
+       2050  CyberSerial (4-port) 16550
+       2051  CyberSerial (4-port) 16650
+       2052  CyberSerial (4-port) 16850
        2060  Trio 2S(16550)+1P
        2061  Trio 2S(16650)+1P
        2062  Trio 2S(16850)+1P
 1395  Ambicom Inc
 1396  Cipher Systems Inc
 1397  Cologne Chip Designs GmbH
-       2bd0  ISDN network controller
+       2bd0  ISDN network controller [HFC-PCI]
+               1397 2bd0 ISDN Board
+               e4bf 1000 CI1-1-Harp
 1398  Clarion co. Ltd
 1399  Rios systems Co Ltd
 139a  Alacritech Inc
 1410  Midas lab Inc
 1411  Ikos Systems Inc
 1412  IC Ensemble Inc
+       1712  ICE1712 [Envy24]
 1413  Addonics
 1414  Microsoft Corporation
 1415  Oxford Semiconductor Ltd
 1517  ECHOTEK Corp
 1518  PEP MODULAR Computers GmbH
 1519  TELEFON AKTIEBOLAGET LM Ericsson
-151a  GLOBETEK Inc
+151a  Globetek
+       1002  PCI-1002
+       1004  PCI-1004
+       1008  PCI-1008
 151b  COMBOX Ltd
 151c  DIGITAL AUDIO LABS Inc
 151d  Fujitsu Computer Products Of America
                103c 10C7  MegaRaid T5
                1111 1111  MegaRaid 466
                113c 03A2  MegaRaid
+       2410  82801 82810 Chipset ISA Bridge (LPC)
+       2411  82801 82810 Chipset IDE
+       2412  82801 82810 Chipset USB
+       2413  82801 82810 Chipset SMBus
+       2418  82801 82810 PCI Bridge
        5200  EtherExpress PRO/100
        5201  EtherExpress PRO/100
        7000  82371SB PIIX3 ISA [Natoma/Triton II]
@@ -3485,6 +3524,7 @@ e159  Tiger Jet Network Inc.
        0001  Model 300 128k
                0059 0001  128k ISDN-S/T Adapter
                0059 0003  128k ISDN-U Adapter
+e4bf  EKF Elektronik GmbH
 eabb  Aashima Technology B.V.
 ecc0  Echo Corporation
 edd8  ARK Logic Inc
index 40c006f4f4b612616e3f224895fa123aa342a2c2..56ca2b46a56e8946a2ef33272693a2de065ab7da 100644 (file)
@@ -306,84 +306,6 @@ void __init proc_bus_pci_add(struct pci_bus *bus)
  *  Backward compatible /proc/pci interface.
  */
 
-static const char *pci_strclass (unsigned int class)
-{
-       switch (class >> 8) {
-             case PCI_CLASS_NOT_DEFINED:               return "Non-VGA device";
-             case PCI_CLASS_NOT_DEFINED_VGA:           return "VGA compatible device";
-
-             case PCI_CLASS_STORAGE_SCSI:              return "SCSI storage controller";
-             case PCI_CLASS_STORAGE_IDE:               return "IDE interface";
-             case PCI_CLASS_STORAGE_FLOPPY:            return "Floppy disk controller";
-             case PCI_CLASS_STORAGE_IPI:               return "IPI bus controller";
-             case PCI_CLASS_STORAGE_RAID:              return "RAID bus controller";
-             case PCI_CLASS_STORAGE_OTHER:             return "Unknown mass storage controller";
-
-             case PCI_CLASS_NETWORK_ETHERNET:          return "Ethernet controller";
-             case PCI_CLASS_NETWORK_TOKEN_RING:        return "Token ring network controller";
-             case PCI_CLASS_NETWORK_FDDI:              return "FDDI network controller";
-             case PCI_CLASS_NETWORK_ATM:               return "ATM network controller";
-             case PCI_CLASS_NETWORK_OTHER:             return "Network controller";
-
-             case PCI_CLASS_DISPLAY_VGA:               return "VGA compatible controller";
-             case PCI_CLASS_DISPLAY_XGA:               return "XGA compatible controller";
-             case PCI_CLASS_DISPLAY_OTHER:             return "Display controller";
-
-             case PCI_CLASS_MULTIMEDIA_VIDEO:          return "Multimedia video controller";
-             case PCI_CLASS_MULTIMEDIA_AUDIO:          return "Multimedia audio controller";
-             case PCI_CLASS_MULTIMEDIA_OTHER:          return "Multimedia controller";
-
-             case PCI_CLASS_MEMORY_RAM:                return "RAM memory";
-             case PCI_CLASS_MEMORY_FLASH:              return "FLASH memory";
-             case PCI_CLASS_MEMORY_OTHER:              return "Memory";
-
-             case PCI_CLASS_BRIDGE_HOST:               return "Host bridge";
-             case PCI_CLASS_BRIDGE_ISA:                return "ISA bridge";
-             case PCI_CLASS_BRIDGE_EISA:               return "EISA bridge";
-             case PCI_CLASS_BRIDGE_MC:                 return "MicroChannel bridge";
-             case PCI_CLASS_BRIDGE_PCI:                return "PCI bridge";
-             case PCI_CLASS_BRIDGE_PCMCIA:             return "PCMCIA bridge";
-             case PCI_CLASS_BRIDGE_NUBUS:              return "NuBus bridge";
-             case PCI_CLASS_BRIDGE_CARDBUS:            return "CardBus bridge";
-             case PCI_CLASS_BRIDGE_OTHER:              return "Bridge";
-
-             case PCI_CLASS_COMMUNICATION_SERIAL:      return "Serial controller";
-             case PCI_CLASS_COMMUNICATION_PARALLEL:    return "Parallel controller";
-             case PCI_CLASS_COMMUNICATION_OTHER:       return "Communication controller";
-
-             case PCI_CLASS_SYSTEM_PIC:                return "PIC";
-             case PCI_CLASS_SYSTEM_DMA:                return "DMA controller";
-             case PCI_CLASS_SYSTEM_TIMER:              return "Timer";
-             case PCI_CLASS_SYSTEM_RTC:                return "RTC";
-             case PCI_CLASS_SYSTEM_OTHER:              return "System peripheral";
-
-             case PCI_CLASS_INPUT_KEYBOARD:            return "Keyboard controller";
-             case PCI_CLASS_INPUT_PEN:                 return "Digitizer Pen";
-             case PCI_CLASS_INPUT_MOUSE:               return "Mouse controller";
-             case PCI_CLASS_INPUT_OTHER:               return "Input device controller";
-
-             case PCI_CLASS_DOCKING_GENERIC:           return "Generic Docking Station";
-             case PCI_CLASS_DOCKING_OTHER:             return "Docking Station";
-
-             case PCI_CLASS_PROCESSOR_386:             return "386";
-             case PCI_CLASS_PROCESSOR_486:             return "486";
-             case PCI_CLASS_PROCESSOR_PENTIUM:         return "Pentium";
-             case PCI_CLASS_PROCESSOR_ALPHA:           return "Alpha";
-             case PCI_CLASS_PROCESSOR_POWERPC:         return "Power PC";
-             case PCI_CLASS_PROCESSOR_CO:              return "Co-processor";
-
-             case PCI_CLASS_SERIAL_FIREWIRE:           return "FireWire (IEEE 1394)";
-             case PCI_CLASS_SERIAL_ACCESS:             return "ACCESS Bus";
-             case PCI_CLASS_SERIAL_SSA:                return "SSA";
-             case PCI_CLASS_SERIAL_USB:                return "USB Controller";
-             case PCI_CLASS_SERIAL_FIBER:              return "Fiber Channel";
-
-             case PCI_CLASS_HOT_SWAP_CONTROLLER:       return "Hot Swap Controller";
-
-             default:                                  return "Unknown class";
-       }
-}
-
 /*
  * Convert some of the configuration space registers of the device at
  * address (bus,devfn) into a string (possibly several lines each).
@@ -392,8 +314,8 @@ static const char *pci_strclass (unsigned int class)
  */
 static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
 {
-       unsigned int class_rev;
-       unsigned char latency, min_gnt, max_lat;
+       u32 class_rev;
+       unsigned char latency, min_gnt, max_lat, *class;
        int reg, len = 0;
 
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
@@ -404,10 +326,12 @@ static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
                return -1;
        len += sprintf(buf + len, "  Bus %2d, device %3d, function %2d:\n",
                       dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-       len += sprintf(buf + len, "    %s: %s (rev %d).\n",
-                      pci_strclass(class_rev >> 8),
-                      dev->name,
-                      class_rev & 0xff);
+       class = pci_class_name(class_rev >> 16);
+       if (class)
+               len += sprintf(buf+len, "    %s", class);
+       else
+               len += sprintf(buf+len, "    Class %04x", class_rev >> 16);
+       len += sprintf(buf+len, ": %s (rev %d).\n", dev->name, class_rev & 0xff);
 
        if (dev->irq) {
                if (len + 40 > size)
@@ -512,7 +436,7 @@ static int __init pci_proc_init(void)
 {
        if (pci_present()) {
                proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
-               create_proc_info_entry("devices",0, proc_bus_pci_dir,
+               create_proc_info_entry("devices", 0, proc_bus_pci_dir,
                                        get_pci_dev_info);
                proc_bus_pci_add(pci_root);
                create_proc_read_entry("pci", 0, NULL, pci_read_proc, NULL);
index 9cbbd2cde68f3e949cbf014f86cda3e76a3273c9..77f52f337f0de2d1e38981a040ab6de423f2def1 100644 (file)
@@ -9084,7 +9084,7 @@ aic7xxx_detect(Scsi_Host_Template *template)
    * aic7xxx_setup
    */
   if(aic7xxx)
-    aic7xxx_setup(aic7xxx, NULL);
+    aic7xxx_setup(aic7xxx);
   if(dummy_buffer[0] != 'P')
     printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
       "/scsi/README.aic7xxx\n"
index 360ac591dc4a1c615fcf874e7c253577aa109377..5ffab8c1e70123d07284221b89c0833c4c26faf1 100644 (file)
@@ -257,7 +257,7 @@ static inline void init_hpc_chain(uchar *buf)
        hcp->desc.pnext = PHYSADDR(buf);
 }
 
-int __init sgiwd93_detect(Scsi_Host_Template *HPsUX)
+int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
 {
        static unsigned char called = 0;
        struct hpc3_scsiregs *hregs = &hpc3c0->scsi_chan0;
@@ -267,9 +267,9 @@ int __init sgiwd93_detect(Scsi_Host_Template *HPsUX)
        if(called)
                return 0; /* Should bitch on the console about this... */
 
-       HPsUX->proc_name = "SGIWD93";
+       SGIblows->proc_name = "SGIWD93";
 
-       sgiwd93_host = scsi_register(HPsUX, sizeof(struct WD33C93_hostdata));
+       sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata));
        sgiwd93_host->base = (unsigned char *) hregs;
        sgiwd93_host->irq = 1;
 
index 75d4cf12f3f0ac9e8e766caa05255ff923333ea3..818b44c79b457fd8e021ea8cc6afdd4291f4d681 100644 (file)
@@ -29,7 +29,6 @@ comment 'Miscellaneous USB options'
    dep_tristate '  EZUSB Firmware downloader' CONFIG_USB_EZUSB $CONFIG_USB
 
 comment 'USB Devices'
-   dep_tristate '  USB hub support (Required!)' CONFIG_USB_HUB $CONFIG_USB
    dep_tristate '  USB mouse support' CONFIG_USB_MOUSE $CONFIG_USB
    dep_tristate '  USB HP scanner support' CONFIG_USB_HP_SCANNER $CONFIG_USB
    dep_tristate '  USB keyboard support' CONFIG_USB_KBD $CONFIG_USB
index 20dca257180f2b4c2570cdb48b469584e78570be..b30ce3d16aff11c566ac843a174098afe4b472af 100644 (file)
@@ -72,14 +72,6 @@ ifeq ($(CONFIG_USB_HP_SCANNER),m)
   MI_OBJS +=hp_scanner.o
 endif
 
-ifeq ($(CONFIG_USB_HUB),y)
-  L_OBJS += hub.o
-endif
-ifeq ($(CONFIG_USB_HUB),m)
-  M_OBJS += hub.o
-  MI_OBJS += hub.o     
-endif
-
 ifeq ($(CONFIG_USB_ACM),y)
   L_OBJS += acm.o
 endif
@@ -212,9 +204,11 @@ usb-ohci-hcd.o: ohci-hcd.o ohci-root-hub.o
        $(LD) $(LD_RFLAG) -r -o $@ ohci-hcd.o ohci-root-hub.o 
 
 ifeq ($(CONFIG_USB_PROC),y)
-usbcore.o: usb.o usb-debug.o usb-core.o proc_usb.o
-       $(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o proc_usb.o
+usbcore.o: usb.o usb-debug.o usb-core.o proc_usb.o hub.o
+       $(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o proc_usb.o \
+       hub.o
 else
-usbcore.o: usb.o usb-debug.o usb-core.o
-       $(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o
+usbcore.o: usb.o usb-debug.o usb-core.o hub.o
+       $(LD) $(LD_RFLAG) -r -o $@ usb.o usb-debug.o usb-core.o \
+       hub.o
 endif
index 385b074f1e8c65b10ae3a8b4292fe456ed8be2fc..4c104dcaebcef5c96a16555042e70305f161e29e 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/list.h>
 #include <linux/malloc.h>
 #include <linux/smp_lock.h>
-#include <linux/module.h>
 #include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
@@ -519,16 +518,3 @@ void usb_hub_cleanup(void)
         */
        usb_deregister(&hub_driver);
 } /* usb_hub_cleanup() */
-
-#ifdef MODULE
-int init_module(void)
-{
-       return usb_hub_init();
-}
-
-void cleanup_module(void)
-{
-       usb_hub_cleanup();
-}
-#endif
-
index 4dd039b4c1d124b47619d12e61a767337fce91c4..80878efd8a639b359b28852a46b8fa7fa369b964 100644 (file)
@@ -33,6 +33,8 @@ int usb_init(void)
 #ifdef CONFIG_USB_PROC
        proc_usb_init();
 #endif
+       usb_hub_init();
+
 #ifndef CONFIG_USB_MODULE
 #      ifdef CONFIG_USB_UHCI
                uhci_init();
@@ -70,9 +72,6 @@ int usb_init(void)
 #      ifdef CONFIG_USB_DC2XX
                usb_dc2xx_init();
 #      endif
-#      ifdef CONFIG_USB_HUB
-               usb_hub_init();
-#      endif
 #      ifdef CONFIG_USB_SCSI
                usb_scsi_init();
 #      endif
@@ -89,10 +88,8 @@ void cleanup_drivers(void)
 #ifdef CONFIG_USB_PROC
        proc_usb_cleanup ();
 #endif
+       usb_hub_cleanup();
 #ifndef MODULE
-#      ifdef CONFIG_USB_HUB
-               usb_hub_cleanup();
-#      endif
 #      ifdef CONFIG_USB_MOUSE
                usb_mouse_cleanup();
 #      endif
index 7a533fb927c0795e3eca0e6d45cc0cad111d3188..c5f571ce1fb745f60e3e9d5bf1c83e81002e1490 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -79,13 +79,18 @@ int do_truncate(struct dentry *dentry, loff_t length)
        return error;
 }
 
-asmlinkage long sys_truncate(const char * path, unsigned long length)
+static inline long do_sys_truncate(const char * path, loff_t length)
 {
        struct dentry * dentry;
        struct inode * inode;
        int error;
 
        lock_kernel();
+
+       error = -EINVAL;
+       if (length < 0) /* sorry, but loff_t says... */
+               goto out;
+
        dentry = namei(path);
 
        error = PTR_ERR(dentry);
@@ -128,13 +133,21 @@ out:
        return error;
 }
 
-asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
+asmlinkage long sys_truncate(const char * path, unsigned long length)
+{
+       return do_sys_truncate(path, length);
+}
+
+static inline long do_sys_ftruncate(unsigned int fd, loff_t length)
 {
        struct inode * inode;
        struct dentry *dentry;
        struct file * file;
        int error;
 
+       error = -EINVAL;
+       if (length < 0)
+               goto out;
        error = -EBADF;
        file = fget(fd);
        if (!file)
@@ -163,6 +176,24 @@ out:
        return error;
 }
 
+asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
+{
+       return do_sys_ftruncate(fd, length);
+}
+
+/* LFS versions of truncate are only needed on 32 bit machines */
+#if BITS_PER_LONG == 32
+asmlinkage long sys_truncate64(const char * path, loff_t length)
+{
+       return do_sys_truncate(path, length);
+}
+
+asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
+{
+       return do_sys_ftruncate(fd, length);
+}
+#endif
+
 #if !(defined(__alpha__) || defined(__ia64__))
 
 /*
index 9211147235f4b8fc46e8db0719b3df9f21733ffd..8678dc583d109d8ec88fee59e95899c960920058 100644 (file)
 #define __NR_vfork             190
 #define __NR_ugetrlimit                191     /* SuS compliant getrlimit */
 #define __NR_mmap2             192
+#define __NR_truncate64                193
+#define __NR_ftruncate64       194
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
new file mode 100644 (file)
index 0000000..1f87c99
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * AGPGART module version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight
+ * Copyright (C) 1999 Xi Graphics
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ */
+
+#ifndef _AGP_BACKEND_H
+#define _AGP_BACKEND_H 1
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define AGPGART_VERSION_MAJOR 0
+#define AGPGART_VERSION_MINOR 99
+
+enum chipset_type {
+       NOT_SUPPORTED,
+       INTEL_GENERIC,
+       INTEL_LX,
+       INTEL_BX,
+       INTEL_GX,
+       INTEL_I810,
+       VIA_GENERIC,
+       VIA_VP3,
+       VIA_MVP3,
+       VIA_APOLLO_PRO,
+       SIS_GENERIC,
+       AMD_GENERIC,
+       AMD_IRONGATE,
+       ALI_M1541,
+       ALI_GENERIC
+};
+
+typedef struct _agp_version {
+       u16 major;
+       u16 minor;
+} agp_version;
+
+typedef struct _agp_kern_info {
+       agp_version version;
+       struct pci_dev *device;
+       enum chipset_type chipset;
+       unsigned long mode;
+       off_t aper_base;
+       size_t aper_size;
+       int max_memory;         /* In pages */
+       int current_memory;
+} agp_kern_info;
+
+/* 
+ * The agp_memory structure has information
+ * about the block of agp memory allocated.
+ * A caller may manipulate the next and prev
+ * pointers to link each allocated item into
+ * a list.  These pointers are ignored by the 
+ * backend.  Everything else should never be
+ * written to, but the caller may read any of
+ * the items to detrimine the status of this
+ * block of agp memory.
+ * 
+ */
+
+typedef struct _agp_memory {
+       int key;
+       struct _agp_memory *next;
+       struct _agp_memory *prev;
+       size_t page_count;
+       int num_scratch_pages;
+       unsigned long *memory;
+       off_t pg_start;
+       u32 type;
+       u8 is_bound;
+       u8 is_flushed;
+} agp_memory;
+
+#define AGP_NORMAL_MEMORY 0
+
+extern void agp_free_memory(agp_memory *);
+
+/*
+ * void agp_free_memory(agp_memory *curr) :
+ * 
+ * This function frees memory associated with
+ * an agp_memory pointer.  It is the only function
+ * that can be called when the backend is not owned
+ * by the caller.  (So it can free memory on client
+ * death.)
+ * 
+ * It takes an agp_memory pointer as an argument.
+ * 
+ */
+
+extern agp_memory *agp_allocate_memory(size_t, u32);
+
+/*
+ * agp_memory *agp_allocate_memory(size_t page_count, u32 type) :
+ * 
+ * This function allocates a group of pages of
+ * a certain type.
+ * 
+ * It takes a size_t argument of the number of pages, and
+ * an u32 argument of the type of memory to be allocated.  
+ * Every agp bridge device will allow you to allocate 
+ * AGP_NORMAL_MEMORY which maps to physical ram.  Any other
+ * type is device dependant.
+ * 
+ * It returns NULL whenever memory is unavailable.
+ * 
+ */
+
+extern void agp_copy_info(agp_kern_info *);
+
+/*
+ * void agp_copy_info(agp_kern_info *info) :
+ * 
+ * This function copies information about the
+ * agp bridge device and the state of the agp
+ * backend into an agp_kern_info pointer.
+ * 
+ * It takes an agp_kern_info pointer as an
+ * argument.  The caller should insure that
+ * this pointer is valid.
+ * 
+ */
+
+extern int agp_bind_memory(agp_memory *, off_t);
+
+/*
+ * int agp_bind_memory(agp_memory *curr, off_t pg_start) :
+ * 
+ * This function binds an agp_memory structure
+ * into the graphics aperture translation table.
+ * 
+ * It takes an agp_memory pointer and an offset into
+ * the graphics aperture translation table as arguments
+ * 
+ * It returns -EINVAL if the pointer == NULL.
+ * It returns -EBUSY if the area of the table
+ * requested is already in use.
+ * 
+ */
+
+extern int agp_unbind_memory(agp_memory *);
+
+/* 
+ * int agp_unbind_memory(agp_memory *curr) :
+ * 
+ * This function removes an agp_memory structure
+ * from the graphics aperture translation table.
+ * 
+ * It takes an agp_memory pointer as an argument.
+ * 
+ * It returns -EINVAL if this piece of agp_memory
+ * is not currently bound to the graphics aperture
+ * translation table or if the agp_memory 
+ * pointer == NULL
+ * 
+ */
+
+extern void agp_enable(u32);
+
+/* 
+ * void agp_enable(u32 mode) :
+ * 
+ * This function initializes the agp point-to-point
+ * connection.
+ * 
+ * It takes an agp mode register as an argument
+ * 
+ */
+
+extern int agp_backend_acquire(void);
+
+/*
+ * int agp_backend_acquire(void) :
+ * 
+ * This Function attempts to acquire the agp
+ * backend.
+ * 
+ * returns -EBUSY if agp is in use,
+ * returns 0 if the caller owns the agp backend
+ */
+
+extern void agp_backend_release(void);
+
+/*
+ * void agp_backend_release(void) :
+ * 
+ * This Function releases the lock on the agp
+ * backend.
+ * 
+ * The caller must insure that the graphics
+ * aperture translation table is read for use
+ * by another entity.  (Ensure that all memory
+ * it bound is unbound.)
+ * 
+ */
+
+#endif                         /* _AGP_BACKEND_H */
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
new file mode 100644 (file)
index 0000000..cc9dc84
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * AGPGART module version 0.99
+ * Copyright (C) 1999 Jeff Hartmann
+ * Copyright (C) 1999 Precision Insight
+ * Copyright (C) 1999 Xi Graphics
+ *
+ * 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
+ * JEFF HARTMANN, 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.
+ *
+ */
+
+#ifndef _AGP_H
+#define _AGP_H 1
+
+#define AGPIOC_BASE       'A'
+#define AGPIOC_INFO       _IOR (AGPIOC_BASE, 0, agp_info*)
+#define AGPIOC_ACQUIRE    _IO  (AGPIOC_BASE, 1)
+#define AGPIOC_RELEASE    _IO  (AGPIOC_BASE, 2)
+#define AGPIOC_SETUP      _IOW (AGPIOC_BASE, 3, agp_setup*)
+#define AGPIOC_RESERVE    _IOW (AGPIOC_BASE, 4, agp_region*)
+#define AGPIOC_PROTECT    _IOW (AGPIOC_BASE, 5, agp_region*)
+#define AGPIOC_ALLOCATE   _IOWR(AGPIOC_BASE, 6, agp_allocate*)
+#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
+#define AGPIOC_BIND       _IOW (AGPIOC_BASE, 8, agp_bind*)
+#define AGPIOC_UNBIND     _IOW (AGPIOC_BASE, 9, agp_unbind*)
+
+#define AGP_DEVICE      "/dev/agpgart"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef __KERNEL__
+#include <linux/types.h>
+#include <asm/types.h>
+
+typedef struct _agp_version {
+       __u16 major;
+       __u16 minor;
+} agp_version;
+
+typedef struct _agp_info {
+       agp_version version;    /* version of the driver        */
+       __u32 bridge_id;        /* bridge vendor/device         */
+       __u32 agp_mode;         /* mode info of bridge          */
+       off_t aper_base;        /* base of aperture             */
+       size_t aper_size;       /* size of aperture             */
+       size_t pg_total;        /* max pages (swap + system)    */
+       size_t pg_system;       /* max pages (system)           */
+       size_t pg_used;         /* current pages used           */
+} agp_info;
+
+typedef struct _agp_setup {
+       __u32 agp_mode;         /* mode info of bridge          */
+} agp_setup;
+
+/*
+ * The "prot" down below needs still a "sleep" flag somehow ...
+ */
+typedef struct _agp_segment {
+       off_t pg_start;         /* starting page to populate    */
+       size_t pg_count;        /* number of pages              */
+       int prot;               /* prot flags for mmap          */
+} agp_segment;
+
+typedef struct _agp_region {
+       pid_t pid;              /* pid of process               */
+       size_t seg_count;       /* number of segments           */
+       struct _agp_segment *seg_list;
+} agp_region;
+
+typedef struct _agp_allocate {
+       int key;                /* tag of allocation            */
+       size_t pg_count;        /* number of pages              */
+       __u32 type;             /* 0 == normal, other devspec   */
+} agp_allocate;
+
+typedef struct _agp_bind {
+       int key;                /* tag of allocation            */
+       off_t pg_start;         /* starting page to populate    */
+} agp_bind;
+
+typedef struct _agp_unbind {
+       int key;                /* tag of allocation            */
+       __u32 priority;         /* priority for paging out      */
+} agp_unbind;
+
+#else                          /* __KERNEL__ */
+
+#define AGPGART_MINOR 175
+
+#define AGP_UNLOCK()           up(&(agp_fe.agp_mutex));
+#define AGP_LOCK()             down(&(agp_fe.agp_mutex));
+#define AGP_LOCK_INIT()        sema_init(&(agp_fe.agp_mutex), 1)
+
+#ifndef _AGP_BACKEND_H
+typedef struct _agp_version {
+       u16 major;
+       u16 minor;
+} agp_version;
+
+#endif
+
+typedef struct _agp_info {
+       agp_version version;    /* version of the driver        */
+       u32 bridge_id;          /* bridge vendor/device         */
+       u32 agp_mode;           /* mode info of bridge          */
+       off_t aper_base;        /* base of aperture             */
+       size_t aper_size;       /* size of aperture             */
+       size_t pg_total;        /* max pages (swap + system)    */
+       size_t pg_system;       /* max pages (system)           */
+       size_t pg_used;         /* current pages used           */
+} agp_info;
+
+typedef struct _agp_setup {
+       u32 agp_mode;           /* mode info of bridge          */
+} agp_setup;
+
+/*
+ * The "prot" down below needs still a "sleep" flag somehow ...
+ */
+typedef struct _agp_segment {
+       off_t pg_start;         /* starting page to populate    */
+       size_t pg_count;        /* number of pages              */
+       int prot;               /* prot flags for mmap          */
+} agp_segment;
+
+typedef struct _agp_segment_priv {
+       off_t pg_start;
+       size_t pg_count;
+       pgprot_t prot;
+} agp_segment_priv;
+
+typedef struct _agp_region {
+       pid_t pid;              /* pid of process               */
+       size_t seg_count;       /* number of segments           */
+       struct _agp_segment *seg_list;
+} agp_region;
+
+typedef struct _agp_allocate {
+       int key;                /* tag of allocation            */
+       size_t pg_count;        /* number of pages              */
+       u32 type;               /* 0 == normal, other devspec   */
+} agp_allocate;
+
+typedef struct _agp_bind {
+       int key;                /* tag of allocation            */
+       off_t pg_start;         /* starting page to populate    */
+} agp_bind;
+
+typedef struct _agp_unbind {
+       int key;                /* tag of allocation            */
+       u32 priority;           /* priority for paging out      */
+} agp_unbind;
+
+typedef struct _agp_client {
+       struct _agp_client *next;
+       struct _agp_client *prev;
+       pid_t pid;
+       int num_segments;
+       agp_segment_priv **segments;
+} agp_client;
+
+typedef struct _agp_controller {
+       struct _agp_controller *next;
+       struct _agp_controller *prev;
+       pid_t pid;
+       int num_clients;
+       agp_memory *pool;
+       agp_client *clients;
+} agp_controller;
+
+#define AGP_FF_ALLOW_CLIENT            0
+#define AGP_FF_ALLOW_CONTROLLER        1
+#define AGP_FF_IS_CLIENT               2
+#define AGP_FF_IS_CONTROLLER           3
+#define AGP_FF_IS_VALID                4
+
+typedef struct _agp_file_private {
+       struct _agp_file_private *next;
+       struct _agp_file_private *prev;
+       pid_t my_pid;
+       u32 access_flags;
+} agp_file_private;
+
+struct agp_front_data {
+       struct semaphore agp_mutex;
+       agp_controller *current_controller;
+       agp_controller *controllers;
+       agp_file_private *file_priv_list;
+       u8 used_by_controller;
+       u8 backend_acquired;
+};
+
+#endif                         /* __KERNEL__ */
+
+#endif                         /* _AGP_H */
index 74af3f0b47d1266f6c08a6892663c4be8f32b12c..f2e47f03a0b83a289c60e5d13ab3b2dbc282ec2b 100644 (file)
@@ -450,6 +450,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 int pci_proc_attach_device(struct pci_dev *dev);
 int pci_proc_detach_device(struct pci_dev *dev);
 void pci_name_device(struct pci_dev *dev);
+char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
 struct resource *pci_find_parent_resource(struct pci_dev *dev, struct resource *res);
 
index 133cb1acb8aab5c9209b09617d230e29606d6b6f..09aedf487a887e55c27528bccc966e5c598f798b 100644 (file)
 #define PCI_BASE_CLASS_DISPLAY         0x03
 #define PCI_CLASS_DISPLAY_VGA          0x0300
 #define PCI_CLASS_DISPLAY_XGA          0x0301
+#define PCI_CLASS_DISPLAY_3D           0x0302
 #define PCI_CLASS_DISPLAY_OTHER                0x0380
 
 #define PCI_BASE_CLASS_MULTIMEDIA      0x04
 #define PCI_CLASS_MULTIMEDIA_VIDEO     0x0400
 #define PCI_CLASS_MULTIMEDIA_AUDIO     0x0401
+#define PCI_CLASS_MULTIMEDIA_PHONE     0x0402
 #define PCI_CLASS_MULTIMEDIA_OTHER     0x0480
 
 #define PCI_BASE_CLASS_MEMORY          0x05
-#define  PCI_CLASS_MEMORY_RAM          0x0500
-#define  PCI_CLASS_MEMORY_FLASH                0x0501
-#define  PCI_CLASS_MEMORY_OTHER                0x0580
+#define PCI_CLASS_MEMORY_RAM           0x0500
+#define PCI_CLASS_MEMORY_FLASH         0x0501
+#define PCI_CLASS_MEMORY_OTHER         0x0580
 
 #define PCI_BASE_CLASS_BRIDGE          0x06
-#define  PCI_CLASS_BRIDGE_HOST         0x0600
-#define  PCI_CLASS_BRIDGE_ISA          0x0601
-#define  PCI_CLASS_BRIDGE_EISA         0x0602
-#define  PCI_CLASS_BRIDGE_MC           0x0603
-#define  PCI_CLASS_BRIDGE_PCI          0x0604
-#define  PCI_CLASS_BRIDGE_PCMCIA       0x0605
-#define  PCI_CLASS_BRIDGE_NUBUS                0x0606
-#define  PCI_CLASS_BRIDGE_CARDBUS      0x0607
-#define  PCI_CLASS_BRIDGE_OTHER                0x0680
+#define PCI_CLASS_BRIDGE_HOST          0x0600
+#define PCI_CLASS_BRIDGE_ISA           0x0601
+#define PCI_CLASS_BRIDGE_EISA          0x0602
+#define PCI_CLASS_BRIDGE_MC            0x0603
+#define PCI_CLASS_BRIDGE_PCI           0x0604
+#define PCI_CLASS_BRIDGE_PCMCIA                0x0605
+#define PCI_CLASS_BRIDGE_NUBUS         0x0606
+#define PCI_CLASS_BRIDGE_CARDBUS       0x0607
+#define PCI_CLASS_BRIDGE_RACEWAY       0x0608
+#define PCI_CLASS_BRIDGE_OTHER         0x0680
 
 #define PCI_BASE_CLASS_COMMUNICATION   0x07
 #define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
 #define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
+#define PCI_CLASS_COMMUNICATION_MODEM  0x0703
 #define PCI_CLASS_COMMUNICATION_OTHER  0x0780
 
 #define PCI_BASE_CLASS_SYSTEM          0x08
 #define PCI_CLASS_SYSTEM_DMA           0x0801
 #define PCI_CLASS_SYSTEM_TIMER         0x0802
 #define PCI_CLASS_SYSTEM_RTC           0x0803
+#define PCI_CLASS_SYSTEM_PCI_HOTPLUG   0x0804
 #define PCI_CLASS_SYSTEM_OTHER         0x0880
 
 #define PCI_BASE_CLASS_INPUT           0x09
 #define PCI_CLASS_INPUT_KEYBOARD       0x0900
 #define PCI_CLASS_INPUT_PEN            0x0901
 #define PCI_CLASS_INPUT_MOUSE          0x0902
+#define PCI_CLASS_INPUT_SCANNER                0x0903
+#define PCI_CLASS_INPUT_GAMEPORT       0x0904
 #define PCI_CLASS_INPUT_OTHER          0x0980
 
 #define PCI_BASE_CLASS_DOCKING         0x0a
 #define PCI_CLASS_DOCKING_GENERIC      0x0a00
-#define PCI_CLASS_DOCKING_OTHER                0x0a01
+#define PCI_CLASS_DOCKING_OTHER                0x0a80
 
 #define PCI_BASE_CLASS_PROCESSOR       0x0b
 #define PCI_CLASS_PROCESSOR_386                0x0b00
@@ -78,6 +86,7 @@
 #define PCI_CLASS_PROCESSOR_PENTIUM    0x0b02
 #define PCI_CLASS_PROCESSOR_ALPHA      0x0b10
 #define PCI_CLASS_PROCESSOR_POWERPC    0x0b20
+#define PCI_CLASS_PROCESSOR_MIPS       0x0b30
 #define PCI_CLASS_PROCESSOR_CO         0x0b40
 
 #define PCI_BASE_CLASS_SERIAL          0x0c
 #define PCI_CLASS_SERIAL_SSA           0x0c02
 #define PCI_CLASS_SERIAL_USB           0x0c03
 #define PCI_CLASS_SERIAL_FIBER         0x0c04
+#define PCI_CLASS_SERIAL_SMBUS         0x0c05
 
 #define PCI_BASE_CLASS_INTELLIGENT     0x0e
 #define PCI_CLASS_INTELLIGENT_I2O      0x0e00
 
-#define PCI_CLASS_HOT_SWAP_CONTROLLER  0xff00
+#define PCI_BASE_CLASS_SATELLITE       0x0f
+#define PCI_CLASS_SATELLITE_TV         0x0f00
+#define PCI_CLASS_SATELLITE_AUDIO      0x0f01
+#define PCI_CLASS_SATELLITE_VOICE      0x0f03
+#define PCI_CLASS_SATELLITE_DATA       0x0f04
+
+#define PCI_BASE_CLASS_CRYPT           0x10
+#define PCI_CLASS_CRYPT_NETWORK                0x1000
+#define PCI_CLASS_CRYPT_ENTERTAINMENT  0x1001
+#define PCI_CLASS_CRYPT_OTHER          0x1080
+
+#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
+#define PCI_CLASS_SP_DPIO              0x1100
+#define PCI_CLASS_SP_OTHER             0x1180
 
 #define PCI_CLASS_OTHERS               0xff
 
index 2dbfe83f77821a4ec5fec1e12d67f93d7ac831a1..7c5f6df21f204cc7a2e15a756cd81799fc91d102 100644 (file)
@@ -9,7 +9,7 @@
 #include <asm/uaccess.h>
 
 /* Note: never hold tasklist_lock while spinning for this one */
-spinlock_t task_capability_lock;
+spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
 
 /*
  * For sys_getproccap() and sys_setproccap(), any of the three