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
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
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
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
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
# 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
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/machvec.h>
-#include <asm/spinlock.h>
#include "proto.h"
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
"$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
define_bool CONFIG_PCI y
+ source drivers/pci/Config.h
fi
#
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
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
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
+CONFIG_PCI_NAMES=y
# CONFIG_MCA is not set
#
.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
* 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
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;
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";
/*
* 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
fi
fi
+source drivers/pci/Config.in
endmenu
bool ' Kernel module loader' CONFIG_KMOD
fi
+source drivers/pci/Config.in
+
endmenu
if [ "$CONFIG_DECSTATION" = "y" ]; then
# CONFIG_SGI is not set
CONFIG_SNI_RM200_PCI=y
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
#
# CPU selection
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
#
# General setup
#
-# CONFIG_PCI is not set
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
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
# CONFIG_SMP is not set
# CONFIG_SUN4 is not set
# CONFIG_PCI is not set
+# CONFIG_PCI_NAMES is not set
#
# Console drivers
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
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
#
# Misc Linux/SPARC drivers
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
endif
endif
+ifeq ($(CONFIG_AGP), m)
+ ALL_SUB_DIRS += agp
+ MOD_SUB_DIRS += agp
+endif
+
include $(TOPDIR)/Rules.make
fastdep:
--- /dev/null
+#
+# 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
*/
#define __NO_VERSION__
+#include <linux/config.h>
#include "drmP.h"
#include "linux/un.h"
#define _DRM_P_H_
#ifdef __KERNEL__
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
*/
#define EXPORT_SYMTAB
+#include <linux/config.h>
#include "drmP.h"
#include "gamma_drv.h"
EXPORT_SYMBOL(gamma_init);
*/
#define EXPORT_SYMTAB
+#include <linux/config.h>
#include "drmP.h"
#include "tdfx_drv.h"
EXPORT_SYMBOL(tdfx_init);
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
#define AIRONET4500_H
// redefined to avoid PCMCIA includes
-#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
*
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
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)
"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>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/bitops.h>
-#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
--- /dev/null
+#
+# PCI configuration
+#
+
+if [ "$CONFIG_PCI" = "y" ]; then
+ bool 'PCI device name database' CONFIG_PCI_NAMES
+fi
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
/*
- * 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>
*/
#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++;
}
}
{
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')))
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;
}
/*
- * $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
*/
#include <linux/pci.h>
#include <linux/init.h>
+#ifdef CONFIG_PCI_NAMES
+
struct pci_device_info {
unsigned short device;
unsigned short seen;
}
}
}
+
+/*
+ * 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
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
# 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]
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
* 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).
*/
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);
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)
{
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);
* 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"
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;
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;
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
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
$(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
#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>
*/
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
-
#ifdef CONFIG_USB_PROC
proc_usb_init();
#endif
+ usb_hub_init();
+
#ifndef CONFIG_USB_MODULE
# ifdef CONFIG_USB_UHCI
uhci_init();
# ifdef CONFIG_USB_DC2XX
usb_dc2xx_init();
# endif
-# ifdef CONFIG_USB_HUB
- usb_hub_init();
-# endif
# ifdef CONFIG_USB_SCSI
usb_scsi_init();
# endif
#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
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);
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)
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__))
/*
#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> */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
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);
#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
#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
#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