]> git.pld-linux.org Git - packages/kernel.git/blame - linux-newagpdist.patch
run depmod before geninitrd and rc-boot
[packages/kernel.git] / linux-newagpdist.patch
CommitLineData
64a11e9b 1--- linux/include/linux/agp_backend.h.newagpdist Fri Feb 11 14:50:45 2000
2+++ linux/include/linux/agp_backend.h Fri Feb 11 14:50:45 2000
3@@ -0,0 +1,224 @@
4+/*
5+ * AGPGART module version 0.99
6+ * Copyright (C) 1999 Jeff Hartmann
7+ * Copyright (C) 1999 Precision Insight
8+ * Copyright (C) 1999 Xi Graphics
9+ *
10+ * Permission is hereby granted, free of charge, to any person obtaining a
11+ * copy of this software and associated documentation files (the "Software"),
12+ * to deal in the Software without restriction, including without limitation
13+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14+ * and/or sell copies of the Software, and to permit persons to whom the
15+ * Software is furnished to do so, subject to the following conditions:
16+ *
17+ * The above copyright notice and this permission notice shall be included
18+ * in all copies or substantial portions of the Software.
19+ *
20+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
24+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
26+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27+ *
28+ */
29+
30+#ifndef _AGP_BACKEND_H
31+#define _AGP_BACKEND_H 1
32+
33+#ifndef TRUE
34+#define TRUE 1
35+#endif
36+
37+#ifndef FALSE
38+#define FALSE 0
39+#endif
40+
41+#define AGPGART_VERSION_MAJOR 0
42+#define AGPGART_VERSION_MINOR 99
43+
44+enum chipset_type {
45+ NOT_SUPPORTED,
46+ INTEL_GENERIC,
47+ INTEL_LX,
48+ INTEL_BX,
49+ INTEL_GX,
50+ INTEL_I810,
51+ VIA_GENERIC,
52+ VIA_VP3,
53+ VIA_MVP3,
54+ VIA_APOLLO_PRO,
55+ SIS_GENERIC,
56+ AMD_GENERIC,
57+ AMD_IRONGATE,
58+ ALI_M1541,
59+ ALI_GENERIC
60+};
61+
62+typedef struct _agp_version {
63+ u16 major;
64+ u16 minor;
65+} agp_version;
66+
67+typedef struct _agp_kern_info {
68+ agp_version version;
69+ struct pci_dev *device;
70+ enum chipset_type chipset;
71+ unsigned long mode;
72+ off_t aper_base;
73+ size_t aper_size;
74+ int max_memory; /* In pages */
75+ int current_memory;
76+} agp_kern_info;
77+
78+/*
79+ * The agp_memory structure has information
80+ * about the block of agp memory allocated.
81+ * A caller may manipulate the next and prev
82+ * pointers to link each allocated item into
83+ * a list. These pointers are ignored by the
84+ * backend. Everything else should never be
85+ * written to, but the caller may read any of
86+ * the items to detrimine the status of this
87+ * block of agp memory.
88+ *
89+ */
90+
91+typedef struct _agp_memory {
92+ int key;
93+ struct _agp_memory *next;
94+ struct _agp_memory *prev;
95+ size_t page_count;
96+ int num_scratch_pages;
97+ unsigned long *memory;
98+ off_t pg_start;
99+ u32 type;
100+ u8 is_bound;
101+ u8 is_flushed;
102+} agp_memory;
103+
104+#define AGP_NORMAL_MEMORY 0
105+
106+extern void agp_free_memory(agp_memory *);
107+
108+/*
109+ * void agp_free_memory(agp_memory *curr) :
110+ *
111+ * This function frees memory associated with
112+ * an agp_memory pointer. It is the only function
113+ * that can be called when the backend is not owned
114+ * by the caller. (So it can free memory on client
115+ * death.)
116+ *
117+ * It takes an agp_memory pointer as an argument.
118+ *
119+ */
120+
121+extern agp_memory *agp_allocate_memory(size_t, u32);
122+
123+/*
124+ * agp_memory *agp_allocate_memory(size_t page_count, u32 type) :
125+ *
126+ * This function allocates a group of pages of
127+ * a certain type.
128+ *
129+ * It takes a size_t argument of the number of pages, and
130+ * an u32 argument of the type of memory to be allocated.
131+ * Every agp bridge device will allow you to allocate
132+ * AGP_NORMAL_MEMORY which maps to physical ram. Any other
133+ * type is device dependant.
134+ *
135+ * It returns NULL whenever memory is unavailable.
136+ *
137+ */
138+
139+extern void agp_copy_info(agp_kern_info *);
140+
141+/*
142+ * void agp_copy_info(agp_kern_info *info) :
143+ *
144+ * This function copies information about the
145+ * agp bridge device and the state of the agp
146+ * backend into an agp_kern_info pointer.
147+ *
148+ * It takes an agp_kern_info pointer as an
149+ * argument. The caller should insure that
150+ * this pointer is valid.
151+ *
152+ */
153+
154+extern int agp_bind_memory(agp_memory *, off_t);
155+
156+/*
157+ * int agp_bind_memory(agp_memory *curr, off_t pg_start) :
158+ *
159+ * This function binds an agp_memory structure
160+ * into the graphics aperture translation table.
161+ *
162+ * It takes an agp_memory pointer and an offset into
163+ * the graphics aperture translation table as arguments
164+ *
165+ * It returns -EINVAL if the pointer == NULL.
166+ * It returns -EBUSY if the area of the table
167+ * requested is already in use.
168+ *
169+ */
170+
171+extern int agp_unbind_memory(agp_memory *);
172+
173+/*
174+ * int agp_unbind_memory(agp_memory *curr) :
175+ *
176+ * This function removes an agp_memory structure
177+ * from the graphics aperture translation table.
178+ *
179+ * It takes an agp_memory pointer as an argument.
180+ *
181+ * It returns -EINVAL if this piece of agp_memory
182+ * is not currently bound to the graphics aperture
183+ * translation table or if the agp_memory
184+ * pointer == NULL
185+ *
186+ */
187+
188+extern void agp_enable(u32);
189+
190+/*
191+ * void agp_enable(u32 mode) :
192+ *
193+ * This function initializes the agp point-to-point
194+ * connection.
195+ *
196+ * It takes an agp mode register as an argument
197+ *
198+ */
199+
200+extern int agp_backend_acquire(void);
201+
202+/*
203+ * int agp_backend_acquire(void) :
204+ *
205+ * This Function attempts to acquire the agp
206+ * backend.
207+ *
208+ * returns -EBUSY if agp is in use,
209+ * returns 0 if the caller owns the agp backend
210+ */
211+
212+extern void agp_backend_release(void);
213+
214+/*
215+ * void agp_backend_release(void) :
216+ *
217+ * This Function releases the lock on the agp
218+ * backend.
219+ *
220+ * The caller must insure that the graphics
221+ * aperture translation table is read for use
222+ * by another entity. (Ensure that all memory
223+ * it bound is unbound.)
224+ *
225+ */
226+
227+#endif /* _AGP_BACKEND_H */
228--- linux/include/linux/agpgart.h.newagpdist Fri Feb 11 14:50:45 2000
229+++ linux/include/linux/agpgart.h Fri Feb 11 14:50:45 2000
230@@ -0,0 +1,216 @@
231+/*
232+ * AGPGART module version 0.99
233+ * Copyright (C) 1999 Jeff Hartmann
234+ * Copyright (C) 1999 Precision Insight
235+ * Copyright (C) 1999 Xi Graphics
236+ *
237+ * Permission is hereby granted, free of charge, to any person obtaining a
238+ * copy of this software and associated documentation files (the "Software"),
239+ * to deal in the Software without restriction, including without limitation
240+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
241+ * and/or sell copies of the Software, and to permit persons to whom the
242+ * Software is furnished to do so, subject to the following conditions:
243+ *
244+ * The above copyright notice and this permission notice shall be included
245+ * in all copies or substantial portions of the Software.
246+ *
247+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
248+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
249+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
250+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
251+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
252+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
253+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254+ *
255+ */
256+
257+#ifndef _AGP_H
258+#define _AGP_H 1
259+
260+#define AGPIOC_BASE 'A'
261+#define AGPIOC_INFO _IOR (AGPIOC_BASE, 0, agp_info*)
262+#define AGPIOC_ACQUIRE _IO (AGPIOC_BASE, 1)
263+#define AGPIOC_RELEASE _IO (AGPIOC_BASE, 2)
264+#define AGPIOC_SETUP _IOW (AGPIOC_BASE, 3, agp_setup*)
265+#define AGPIOC_RESERVE _IOW (AGPIOC_BASE, 4, agp_region*)
266+#define AGPIOC_PROTECT _IOW (AGPIOC_BASE, 5, agp_region*)
267+#define AGPIOC_ALLOCATE _IOWR(AGPIOC_BASE, 6, agp_allocate*)
268+#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
269+#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, agp_bind*)
270+#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, agp_unbind*)
271+
272+#define AGP_DEVICE "/dev/agpgart"
273+
274+#ifndef TRUE
275+#define TRUE 1
276+#endif
277+
278+#ifndef FALSE
279+#define FALSE 0
280+#endif
281+
282+#ifndef __KERNEL__
283+#include <linux/types.h>
284+#include <asm/types.h>
285+
286+typedef struct _agp_version {
287+ __u16 major;
288+ __u16 minor;
289+} agp_version;
290+
291+typedef struct _agp_info {
292+ agp_version version; /* version of the driver */
293+ __u32 bridge_id; /* bridge vendor/device */
294+ __u32 agp_mode; /* mode info of bridge */
295+ off_t aper_base; /* base of aperture */
296+ size_t aper_size; /* size of aperture */
297+ size_t pg_total; /* max pages (swap + system) */
298+ size_t pg_system; /* max pages (system) */
299+ size_t pg_used; /* current pages used */
300+} agp_info;
301+
302+typedef struct _agp_setup {
303+ __u32 agp_mode; /* mode info of bridge */
304+} agp_setup;
305+
306+/*
307+ * The "prot" down below needs still a "sleep" flag somehow ...
308+ */
309+typedef struct _agp_segment {
310+ off_t pg_start; /* starting page to populate */
311+ size_t pg_count; /* number of pages */
312+ int prot; /* prot flags for mmap */
313+} agp_segment;
314+
315+typedef struct _agp_region {
316+ pid_t pid; /* pid of process */
317+ size_t seg_count; /* number of segments */
318+ struct _agp_segment *seg_list;
319+} agp_region;
320+
321+typedef struct _agp_allocate {
322+ int key; /* tag of allocation */
323+ size_t pg_count; /* number of pages */
324+ __u32 type; /* 0 == normal, other devspec */
325+} agp_allocate;
326+
327+typedef struct _agp_bind {
328+ int key; /* tag of allocation */
329+ off_t pg_start; /* starting page to populate */
330+} agp_bind;
331+
332+typedef struct _agp_unbind {
333+ int key; /* tag of allocation */
334+ __u32 priority; /* priority for paging out */
335+} agp_unbind;
336+
337+#else /* __KERNEL__ */
338+
339+#define AGPGART_MINOR 175
340+
341+#define AGP_UNLOCK() up(&(agp_fe.agp_mutex));
342+#define AGP_LOCK() down(&(agp_fe.agp_mutex));
343+#define AGP_LOCK_INIT() sema_init(&(agp_fe.agp_mutex), 1)
344+
345+#ifndef _AGP_BACKEND_H
346+typedef struct _agp_version {
347+ u16 major;
348+ u16 minor;
349+} agp_version;
350+
351+#endif
352+
353+typedef struct _agp_info {
354+ agp_version version; /* version of the driver */
355+ u32 bridge_id; /* bridge vendor/device */
356+ u32 agp_mode; /* mode info of bridge */
357+ off_t aper_base; /* base of aperture */
358+ size_t aper_size; /* size of aperture */
359+ size_t pg_total; /* max pages (swap + system) */
360+ size_t pg_system; /* max pages (system) */
361+ size_t pg_used; /* current pages used */
362+} agp_info;
363+
364+typedef struct _agp_setup {
365+ u32 agp_mode; /* mode info of bridge */
366+} agp_setup;
367+
368+/*
369+ * The "prot" down below needs still a "sleep" flag somehow ...
370+ */
371+typedef struct _agp_segment {
372+ off_t pg_start; /* starting page to populate */
373+ size_t pg_count; /* number of pages */
374+ int prot; /* prot flags for mmap */
375+} agp_segment;
376+
377+typedef struct _agp_segment_priv {
378+ off_t pg_start;
379+ size_t pg_count;
380+ pgprot_t prot;
381+} agp_segment_priv;
382+
383+typedef struct _agp_region {
384+ pid_t pid; /* pid of process */
385+ size_t seg_count; /* number of segments */
386+ struct _agp_segment *seg_list;
387+} agp_region;
388+
389+typedef struct _agp_allocate {
390+ int key; /* tag of allocation */
391+ size_t pg_count; /* number of pages */
392+ u32 type; /* 0 == normal, other devspec */
393+} agp_allocate;
394+
395+typedef struct _agp_bind {
396+ int key; /* tag of allocation */
397+ off_t pg_start; /* starting page to populate */
398+} agp_bind;
399+
400+typedef struct _agp_unbind {
401+ int key; /* tag of allocation */
402+ u32 priority; /* priority for paging out */
403+} agp_unbind;
404+
405+typedef struct _agp_client {
406+ struct _agp_client *next;
407+ struct _agp_client *prev;
408+ pid_t pid;
409+ int num_segments;
410+ agp_segment_priv **segments;
411+} agp_client;
412+
413+typedef struct _agp_controller {
414+ struct _agp_controller *next;
415+ struct _agp_controller *prev;
416+ pid_t pid;
417+ int num_clients;
418+ agp_memory *pool;
419+ agp_client *clients;
420+} agp_controller;
421+
422+#define AGP_FF_ALLOW_CLIENT 0
423+#define AGP_FF_ALLOW_CONTROLLER 1
424+#define AGP_FF_IS_CLIENT 2
425+#define AGP_FF_IS_CONTROLLER 3
426+#define AGP_FF_IS_VALID 4
427+
428+typedef struct _agp_file_private {
429+ struct _agp_file_private *next;
430+ struct _agp_file_private *prev;
431+ pid_t my_pid;
432+ u32 access_flags;
433+} agp_file_private;
434+
435+struct agp_front_data {
436+ struct semaphore agp_mutex;
437+ agp_controller *current_controller;
438+ agp_controller *controllers;
439+ agp_file_private *file_priv_list;
440+ u8 used_by_controller;
441+ u8 backend_acquired;
442+};
443+
444+#endif /* __KERNEL__ */
445+
446+#endif /* _AGP_H */
447--- linux/drivers/char/agp/Makefile.newagpdist Fri Feb 11 14:50:45 2000
448+++ linux/drivers/char/agp/Makefile Fri Feb 11 14:50:45 2000
449@@ -0,0 +1,32 @@
450+#
451+# Makefile for the agpgart device driver. This driver adds a user
452+# space ioctl interface to use agp memory. It also adds a kernel interface
453+# that other drivers could use to manipulate agp memory.
454+
455+M_OBJS := agpgart.o
456+
457+CFLAGS_agp_backend.o :=
458+
459+ifdef CONFIG_AGP_I810
460+CFLAGS_agp_backend.o += -DAGP_BUILD_INTEL_I810
461+endif
462+ifdef CONFIG_AGP_INTEL
463+CFLAGS_agp_backend.o += -DAGP_BUILD_INTEL_GENERIC
464+endif
465+ifdef CONFIG_AGP_VIA
466+CFLAGS_agp_backend.o += -DAGP_BUILD_VIA_GENERIC
467+endif
468+ifdef CONFIG_AGP_AMD
469+CFLAGS_agp_backend.o += -DAGP_BUILD_AMD_IRONGATE
470+endif
471+ifdef CONFIG_AGP_SIS
472+CFLAGS_agp_backend.o += -DAGP_BUILD_SIS_GENERIC
473+endif
474+ifdef CONFIG_AGP_ALI
475+CFLAGS_agp_backend.o += -DAGP_BUILD_ALI_M1541
476+endif
477+
478+include $(TOPDIR)/Rules.make
479+
480+agpgart.o: agp_backend.o agpgart_fe.o
481+ $(LD) $(LD_RFLAG) -r -o $@ agp_backend.o agpgart_fe.o
482--- linux/drivers/char/agp/agp_backend.c.newagpdist Fri Feb 11 14:50:45 2000
483+++ linux/drivers/char/agp/agp_backend.c Fri Feb 11 14:50:45 2000
484@@ -0,0 +1,1983 @@
485+/*
486+ * AGPGART module version 0.99
487+ * Copyright (C) 1999 Jeff Hartmann
488+ * Copyright (C) 1999 Precision Insight
489+ * Copyright (C) 1999 Xi Graphics
490+ *
491+ * Permission is hereby granted, free of charge, to any person obtaining a
492+ * copy of this software and associated documentation files (the "Software"),
493+ * to deal in the Software without restriction, including without limitation
494+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
495+ * and/or sell copies of the Software, and to permit persons to whom the
496+ * Software is furnished to do so, subject to the following conditions:
497+ *
498+ * The above copyright notice and this permission notice shall be included
499+ * in all copies or substantial portions of the Software.
500+ *
501+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
502+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
503+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
504+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
505+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
506+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
507+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
508+ *
509+ */
510+#define EXPORT_SYMTAB
511+#include <linux/config.h>
512+#include <linux/version.h>
513+#include <linux/module.h>
514+#include <linux/types.h>
515+#include <linux/kernel.h>
516+#include <linux/sched.h>
517+#include <linux/mm.h>
518+#include <linux/string.h>
519+#include <linux/errno.h>
520+#include <linux/malloc.h>
521+#include <linux/vmalloc.h>
522+#include <linux/pci.h>
523+#include <linux/init.h>
524+#include <linux/pagemap.h>
525+#include <linux/miscdevice.h>
526+#include <asm/system.h>
527+#include <asm/uaccess.h>
528+#include <asm/system.h>
529+#include <asm/io.h>
530+#include <asm/page.h>
531+
532+#include <linux/agp_backend.h>
533+#include "agp_backendP.h"
534+
535+static struct agp_bridge_data agp_bridge;
536+
537+#define CACHE_FLUSH agp_bridge.cache_flush
538+
539+MODULE_AUTHOR("Jeff Hartmann <jhartmann@precisioninsight.com>");
540+MODULE_PARM(agp_try_unsupported, "1i");
541+EXPORT_SYMBOL(agp_free_memory);
542+EXPORT_SYMBOL(agp_allocate_memory);
543+EXPORT_SYMBOL(agp_copy_info);
544+EXPORT_SYMBOL(agp_bind_memory);
545+EXPORT_SYMBOL(agp_unbind_memory);
546+EXPORT_SYMBOL(agp_enable);
547+EXPORT_SYMBOL(agp_backend_acquire);
548+EXPORT_SYMBOL(agp_backend_release);
549+
550+static int agp_try_unsupported __initdata = 0;
551+
552+#ifdef __SMP__
553+static atomic_t cpus_waiting;
554+#endif
555+
556+int agp_backend_acquire(void)
557+{
558+ atomic_inc(&(agp_bridge.agp_in_use));
559+
560+ if (atomic_read(&(agp_bridge.agp_in_use)) != 1) {
561+ atomic_dec(&(agp_bridge.agp_in_use));
562+ return -EBUSY;
563+ }
564+ MOD_INC_USE_COUNT;
565+ return 0;
566+}
567+
568+void agp_backend_release(void)
569+{
570+ atomic_dec(&(agp_bridge.agp_in_use));
571+ MOD_DEC_USE_COUNT;
572+}
573+
574+static void flush_cache(void)
575+{
576+ asm volatile ("wbinvd":::"memory");
577+}
578+
579+#ifdef __SMP__
580+static void ipi_handler(void *null)
581+{
582+ flush_cache();
583+ atomic_dec(&cpus_waiting);
584+ while (atomic_read(&cpus_waiting) > 0)
585+ barrier();
586+}
587+
588+static void smp_flush_cache(void)
589+{
590+ atomic_set(&cpus_waiting, smp_num_cpus - 1);
591+ if (smp_call_function(ipi_handler, NULL, 1, 0) != 0)
592+ panic("agpgart: timed out waiting for the other CPUs!\n");
593+ flush_cache();
594+ while (atomic_read(&cpus_waiting) > 0)
595+ barrier();
596+}
597+#endif
598+
599+/*
600+ * Basic Page Allocation Routines -
601+ * These routines handle page allocation
602+ * and by default they reserve the allocated
603+ * memory. They also handle incrementing the
604+ * current_memory_agp value, Which is checked
605+ * against a maximum value.
606+ */
607+
608+static void *agp_alloc_page(void)
609+{
610+ void *pt;
611+
612+ pt = (void *) __get_free_page(GFP_KERNEL);
613+ if (pt == NULL) {
614+ return NULL;
615+ }
616+ atomic_inc(&(mem_map[MAP_NR(pt)].count));
617+ set_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
618+ atomic_inc(&(agp_bridge.current_memory_agp));
619+ return pt;
620+}
621+
622+static void agp_destroy_page(void *pt)
623+{
624+ if (pt == NULL)
625+ return;
626+
627+ atomic_dec(&(mem_map[MAP_NR(pt)].count));
628+ clear_bit(PG_locked, &mem_map[MAP_NR(pt)].flags);
629+ free_page((unsigned long) pt);
630+ atomic_dec(&(agp_bridge.current_memory_agp));
631+}
632+
633+/* End Basic Page Allocation Routines */
634+
635+/*
636+ * Generic routines for handling agp_memory structures -
637+ * They use the basic page allocation routines to do the
638+ * brunt of the work.
639+ */
640+
641+#define MAXKEY (4096 * 32)
642+
643+static void agp_free_key(int key)
644+{
645+
646+ if (key < 0) {
647+ return;
648+ }
649+ if (key < MAXKEY) {
650+ clear_bit(key, agp_bridge.key_list);
651+ }
652+}
653+
654+static int agp_get_key(void)
655+{
656+ int bit;
657+
658+ bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
659+ if (bit < MAXKEY) {
660+ set_bit(bit, agp_bridge.key_list);
661+ return bit;
662+ }
663+ return -1;
664+}
665+
666+static agp_memory *agp_create_memory(int scratch_pages)
667+{
668+ agp_memory *new;
669+
670+ new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
671+
672+ if (new == NULL) {
673+ return NULL;
674+ }
675+ memset(new, 0, sizeof(agp_memory));
676+ new->key = agp_get_key();
677+
678+ if (new->key < 0) {
679+ kfree(new);
680+ return NULL;
681+ }
682+ new->memory = vmalloc(PAGE_SIZE * scratch_pages);
683+
684+ if (new->memory == NULL) {
685+ agp_free_key(new->key);
686+ kfree(new);
687+ return NULL;
688+ }
689+ new->num_scratch_pages = scratch_pages;
690+ return new;
691+}
692+
693+void agp_free_memory(agp_memory * curr)
694+{
695+ int i;
696+
697+ if (curr == NULL) {
698+ return;
699+ }
700+ if (curr->is_bound == TRUE) {
701+ agp_unbind_memory(curr);
702+ }
703+ if (curr->type != 0) {
704+ agp_bridge.free_by_type(curr);
705+ MOD_DEC_USE_COUNT;
706+ return;
707+ }
708+ if (curr->page_count != 0) {
709+ for (i = 0; i < curr->page_count; i++) {
710+ curr->memory[i] &= ~(0x00000fff);
711+ agp_destroy_page((void *) phys_to_virt(curr->memory[i]));
712+ }
713+ }
714+ agp_free_key(curr->key);
715+ vfree(curr->memory);
716+ kfree(curr);
717+ MOD_DEC_USE_COUNT;
718+}
719+
720+#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
721+
722+agp_memory *agp_allocate_memory(size_t page_count, u32 type)
723+{
724+ int scratch_pages;
725+ agp_memory *new;
726+ int i;
727+
728+ if ((atomic_read(&(agp_bridge.current_memory_agp)) + page_count) >
729+ agp_bridge.max_memory_agp) {
730+ return NULL;
731+ }
732+ if (type != 0) {
733+ new = agp_bridge.alloc_by_type(page_count, type);
734+ return new;
735+ }
736+ scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
737+
738+ new = agp_create_memory(scratch_pages);
739+
740+ if (new == NULL) {
741+ return NULL;
742+ }
743+ for (i = 0; i < page_count; i++) {
744+ new->memory[i] = (unsigned long) agp_alloc_page();
745+
746+ if ((void *) new->memory[i] == NULL) {
747+ /* Free this structure */
748+ agp_free_memory(new);
749+ return NULL;
750+ }
751+ new->memory[i] =
752+ agp_bridge.mask_memory(virt_to_phys((void *) new->memory[i]), type);
753+ new->page_count++;
754+ }
755+
756+ MOD_INC_USE_COUNT;
757+ return new;
758+}
759+
760+/* End - Generic routines for handling agp_memory structures */
761+
762+static int agp_return_size(void)
763+{
764+ int current_size;
765+ void *temp;
766+
767+ temp = agp_bridge.current_size;
768+
769+ switch (agp_bridge.size_type) {
770+ case U8_APER_SIZE:
771+ current_size = ((aper_size_info_8 *) temp)->size;
772+ break;
773+ case U16_APER_SIZE:
774+ current_size = ((aper_size_info_16 *) temp)->size;
775+ break;
776+ case U32_APER_SIZE:
777+ current_size = ((aper_size_info_32 *) temp)->size;
778+ break;
779+ case FIXED_APER_SIZE:
780+ current_size = ((aper_size_info_fixed *) temp)->size;
781+ break;
782+ default:
783+ current_size = 0;
784+ break;
785+ }
786+
787+ return current_size;
788+}
789+
790+/* Routine to copy over information structure */
791+
792+void agp_copy_info(agp_kern_info * info)
793+{
794+ memset(info, 0, sizeof(agp_kern_info));
795+ info->version.major = agp_bridge.version->major;
796+ info->version.minor = agp_bridge.version->minor;
797+ info->device = agp_bridge.dev;
798+ info->chipset = agp_bridge.type;
799+ info->mode = agp_bridge.mode;
800+ info->aper_base = agp_bridge.gart_bus_addr;
801+ info->aper_size = agp_return_size();
802+ info->max_memory = agp_bridge.max_memory_agp;
803+ info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
804+}
805+
806+/* End - Routine to copy over information structure */
807+
808+/*
809+ * Routines for handling swapping of agp_memory into the GATT -
810+ * These routines take agp_memory and insert them into the GATT.
811+ * They call device specific routines to actually write to the GATT.
812+ */
813+
814+int agp_bind_memory(agp_memory * curr, off_t pg_start)
815+{
816+ int ret_val;
817+
818+ if ((curr == NULL) || (curr->is_bound == TRUE)) {
819+ return -EINVAL;
820+ }
821+ if (curr->is_flushed == FALSE) {
822+ CACHE_FLUSH();
823+ curr->is_flushed = TRUE;
824+ }
825+ ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
826+
827+ if (ret_val != 0) {
828+ return ret_val;
829+ }
830+ curr->is_bound = TRUE;
831+ curr->pg_start = pg_start;
832+ return 0;
833+}
834+
835+int agp_unbind_memory(agp_memory * curr)
836+{
837+ int ret_val;
838+
839+ if (curr == NULL) {
840+ return -EINVAL;
841+ }
842+ if (curr->is_bound != TRUE) {
843+ return -EINVAL;
844+ }
845+ ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
846+
847+ if (ret_val != 0) {
848+ return ret_val;
849+ }
850+ curr->is_bound = FALSE;
851+ curr->pg_start = 0;
852+ return 0;
853+}
854+
855+/* End - Routines for handling swapping of agp_memory into the GATT */
856+
857+/*
858+ * Driver routines - start
859+ * Currently this module supports the
860+ * i810, 440lx, 440bx, 440gx, via vp3, via mvp3,
861+ * amd irongate, ALi M1541 and generic support for the
862+ * SiS chipsets.
863+ */
864+
865+/* Generic Agp routines - Start */
866+
867+static void agp_generic_agp_enable(u32 mode)
868+{
869+ struct pci_dev *device = NULL;
870+ u32 command, scratch, cap_id;
871+ u8 cap_ptr;
872+
873+ pci_read_config_dword(agp_bridge.dev,
874+ agp_bridge.capndx + 4,
875+ &command);
876+
877+ /*
878+ * PASS1: go throu all devices that claim to be
879+ * AGP devices and collect their data.
880+ */
881+
882+ while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
883+ pci_read_config_dword(device, 0x04, &scratch);
884+
885+ if (!(scratch & 0x00100000))
886+ continue;
887+
888+ pci_read_config_byte(device, 0x34, &cap_ptr);
889+
890+ if (cap_ptr != 0x00) {
891+ do {
892+ pci_read_config_dword(device, cap_ptr, &cap_id);
893+
894+ if ((cap_id & 0xff) != 0x02)
895+ cap_ptr = (cap_id >> 8) & 0xff;
896+ }
897+ while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
898+ }
899+ if (cap_ptr != 0x00) {
900+ /*
901+ * Ok, here we have a AGP device. Disable impossible settings,
902+ * and adjust the readqueue to the minimum.
903+ */
904+
905+ pci_read_config_dword(device, cap_ptr + 4, &scratch);
906+
907+ /* adjust RQ depth */
908+ command =
909+ ((command & ~0xff000000) |
910+ min((mode & 0xff000000), min((command & 0xff000000), (scratch & 0xff000000))));
911+
912+ /* disable SBA if it's not supported */
913+ if (!((command & 0x00000200) && (scratch & 0x00000200) && (mode & 0x00000200)))
914+ command &= ~0x00000200;
915+
916+ /* disable FW if it's not supported */
917+ if (!((command & 0x00000010) && (scratch & 0x00000010) && (mode & 0x00000010)))
918+ command &= ~0x00000010;
919+
920+ if (!((command & 4) && (scratch & 4) && (mode & 4)))
921+ command &= ~0x00000004;
922+
923+ if (!((command & 2) && (scratch & 2) && (mode & 2)))
924+ command &= ~0x00000002;
925+
926+ if (!((command & 1) && (scratch & 1) && (mode & 1)))
927+ command &= ~0x00000001;
928+ }
929+ }
930+ /*
931+ * PASS2: Figure out the 4X/2X/1X setting and enable the
932+ * target (our motherboard chipset).
933+ */
934+
935+ if (command & 4) {
936+ command &= ~3; /* 4X */
937+ }
938+ if (command & 2) {
939+ command &= ~5; /* 2X */
940+ }
941+ if (command & 1) {
942+ command &= ~6; /* 1X */
943+ }
944+ command |= 0x00000100;
945+
946+ pci_write_config_dword(agp_bridge.dev,
947+ agp_bridge.capndx + 8,
948+ command);
949+
950+ /*
951+ * PASS3: Go throu all AGP devices and update the
952+ * command registers.
953+ */
954+
955+ while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, device)) != NULL) {
956+ pci_read_config_dword(device, 0x04, &scratch);
957+
958+ if (!(scratch & 0x00100000))
959+ continue;
960+
961+ pci_read_config_byte(device, 0x34, &cap_ptr);
962+
963+ if (cap_ptr != 0x00) {
964+ do {
965+ pci_read_config_dword(device, cap_ptr, &cap_id);
966+
967+ if ((cap_id & 0xff) != 0x02)
968+ cap_ptr = (cap_id >> 8) & 0xff;
969+ }
970+ while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
971+ }
972+ if (cap_ptr != 0x00)
973+ pci_write_config_dword(device, cap_ptr + 8, command);
974+ }
975+}
976+
977+static int agp_generic_create_gatt_table(void)
978+{
979+ char *table;
980+ char *table_end;
981+ int size;
982+ int page_order;
983+ int num_entries;
984+ int i;
985+ void *temp;
986+
987+ table = NULL;
988+ i = agp_bridge.aperture_size_idx;
989+ temp = agp_bridge.current_size;
990+ size = page_order = num_entries = 0;
991+
992+ if (agp_bridge.size_type != FIXED_APER_SIZE) {
993+ do {
994+ switch (agp_bridge.size_type) {
995+ case U8_APER_SIZE:
996+ size = ((aper_size_info_8 *) temp)->size;
997+ page_order = ((aper_size_info_8 *) temp)->page_order;
998+ num_entries = ((aper_size_info_8 *) temp)->num_entries;
999+ break;
1000+ case U16_APER_SIZE:
1001+ size = ((aper_size_info_16 *) temp)->size;
1002+ page_order = ((aper_size_info_16 *) temp)->page_order;
1003+ num_entries = ((aper_size_info_16 *) temp)->num_entries;
1004+ break;
1005+ case U32_APER_SIZE:
1006+ size = ((aper_size_info_32 *) temp)->size;
1007+ page_order = ((aper_size_info_32 *) temp)->page_order;
1008+ num_entries = ((aper_size_info_32 *) temp)->num_entries;
1009+ break;
1010+ /* This case will never really happen */
1011+ case FIXED_APER_SIZE:
1012+ default:
1013+ size = page_order = num_entries = 0;
1014+ break;
1015+ }
1016+
1017+ table = (char *) __get_free_pages(GFP_KERNEL, page_order);
1018+
1019+ if (table == NULL) {
1020+ i++;
1021+
1022+ switch (agp_bridge.size_type) {
1023+ case U8_APER_SIZE:
1024+ agp_bridge.current_size = (((aper_size_info_8 *) agp_bridge.aperture_sizes) + i);
1025+ break;
1026+ case U16_APER_SIZE:
1027+ agp_bridge.current_size = (((aper_size_info_16 *) agp_bridge.aperture_sizes) + i);
1028+ break;
1029+ case U32_APER_SIZE:
1030+ agp_bridge.current_size = (((aper_size_info_32 *) agp_bridge.aperture_sizes) + i);
1031+ break;
1032+ /* This case will never really happen */
1033+ case FIXED_APER_SIZE:
1034+ default:
1035+ size = page_order = num_entries = 0;
1036+ break;
1037+ }
1038+ } else {
1039+ agp_bridge.aperture_size_idx = i;
1040+ }
1041+ } while ((table == NULL) && (i < agp_bridge.num_aperture_sizes));
1042+ } else {
1043+ size = ((aper_size_info_fixed *) temp)->size;
1044+ page_order = ((aper_size_info_fixed *) temp)->page_order;
1045+ num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1046+ table = (char *) __get_free_pages(GFP_KERNEL, page_order);
1047+ }
1048+
1049+ if (table == NULL) {
1050+ return -ENOMEM;
1051+ }
1052+ table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
1053+
1054+ for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1055+ set_bit(PG_reserved, &mem_map[i].flags);
1056+ }
1057+
1058+ agp_bridge.gatt_table_real = (unsigned long *) table;
1059+ CACHE_FLUSH();
1060+ agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
1061+ (PAGE_SIZE * (1 << page_order)));
1062+ CACHE_FLUSH();
1063+
1064+ if (agp_bridge.gatt_table == NULL) {
1065+ for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1066+ clear_bit(PG_reserved, &mem_map[i].flags);
1067+ }
1068+
1069+ free_pages((unsigned long) table, page_order);
1070+
1071+ return -ENOMEM;
1072+ }
1073+ agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
1074+
1075+ for (i = 0; i < num_entries; i++) {
1076+ agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
1077+ }
1078+
1079+ return 0;
1080+}
1081+
1082+static int agp_generic_free_gatt_table(void)
1083+{
1084+ int i;
1085+ int page_order;
1086+ char *table, *table_end;
1087+ void *temp;
1088+
1089+ temp = agp_bridge.current_size;
1090+
1091+ switch (agp_bridge.size_type) {
1092+ case U8_APER_SIZE:
1093+ page_order = ((aper_size_info_8 *) temp)->page_order;
1094+ break;
1095+ case U16_APER_SIZE:
1096+ page_order = ((aper_size_info_16 *) temp)->page_order;
1097+ break;
1098+ case U32_APER_SIZE:
1099+ page_order = ((aper_size_info_32 *) temp)->page_order;
1100+ break;
1101+ case FIXED_APER_SIZE:
1102+ page_order = ((aper_size_info_fixed *) temp)->page_order;
1103+ break;
1104+ default:
1105+ page_order = 0;
1106+ break;
1107+ }
1108+
1109+ /* Do not worry about freeing memory, because if this is
1110+ * called, then all agp memory is deallocated and removed
1111+ * from the table.
1112+ */
1113+
1114+ iounmap(agp_bridge.gatt_table);
1115+ table = (char *) agp_bridge.gatt_table_real;
1116+ table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
1117+
1118+ for (i = MAP_NR(table); i < MAP_NR(table_end); i++) {
1119+ clear_bit(PG_reserved, &mem_map[i].flags);
1120+ }
1121+
1122+ free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
1123+ return 0;
1124+}
1125+
1126+static int agp_generic_insert_memory(agp_memory * mem,
1127+ off_t pg_start, int type)
1128+{
1129+ int i, j, num_entries;
1130+ void *temp;
1131+
1132+ temp = agp_bridge.current_size;
1133+
1134+ switch (agp_bridge.size_type) {
1135+ case U8_APER_SIZE:
1136+ num_entries = ((aper_size_info_8 *) temp)->num_entries;
1137+ break;
1138+ case U16_APER_SIZE:
1139+ num_entries = ((aper_size_info_16 *) temp)->num_entries;
1140+ break;
1141+ case U32_APER_SIZE:
1142+ num_entries = ((aper_size_info_32 *) temp)->num_entries;
1143+ break;
1144+ case FIXED_APER_SIZE:
1145+ num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1146+ break;
1147+ default:
1148+ num_entries = 0;
1149+ break;
1150+ }
1151+
1152+ if (type != 0 || mem->type != 0) {
1153+ /* The generic routines know nothing of memory types */
1154+ return -EINVAL;
1155+ }
1156+ if ((pg_start + mem->page_count) > num_entries) {
1157+ return -EINVAL;
1158+ }
1159+ j = pg_start;
1160+
1161+ while (j < (pg_start + mem->page_count)) {
1162+ if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
1163+ return -EBUSY;
1164+ }
1165+ j++;
1166+ }
1167+
1168+ if (mem->is_flushed == FALSE) {
1169+ CACHE_FLUSH();
1170+ mem->is_flushed = TRUE;
1171+ }
1172+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1173+ agp_bridge.gatt_table[j] = mem->memory[i];
1174+ }
1175+
1176+ agp_bridge.tlb_flush(mem);
1177+ return 0;
1178+}
1179+
1180+static int agp_generic_remove_memory(agp_memory * mem, off_t pg_start,
1181+ int type)
1182+{
1183+ int i;
1184+
1185+ if (type != 0 || mem->type != 0) {
1186+ /* The generic routines know nothing of memory types */
1187+ return -EINVAL;
1188+ }
1189+ for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1190+ agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
1191+ }
1192+
1193+ agp_bridge.tlb_flush(mem);
1194+ return 0;
1195+}
1196+
1197+static agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
1198+{
1199+ return NULL;
1200+}
1201+
1202+static void agp_generic_free_by_type(agp_memory * curr)
1203+{
1204+ if (curr->memory != NULL) {
1205+ vfree(curr->memory);
1206+ }
1207+ agp_free_key(curr->key);
1208+ kfree(curr);
1209+}
1210+
1211+void agp_enable(u32 mode)
1212+{
1213+ agp_bridge.agp_enable(mode);
1214+}
1215+
1216+/* End - Generic Agp routines */
1217+
1218+#ifdef AGP_BUILD_INTEL_I810
1219+
1220+static aper_size_info_fixed intel_i810_sizes[] =
1221+{
1222+ {64, 16384, 4},
1223+ /* The 32M mode still requires a 64k gatt */
1224+ {32, 8192, 4}
1225+};
1226+
1227+#define AGP_DCACHE_MEMORY 1
1228+
1229+static gatt_mask intel_i810_masks[] =
1230+{
1231+ {I810_PTE_VALID, 0},
1232+ {(I810_PTE_VALID | I810_PTE_LOCAL), AGP_DCACHE_MEMORY}
1233+};
1234+
1235+static struct _intel_i810_private {
1236+ struct pci_dev *i810_dev; /* device one */
1237+ volatile unsigned char *registers;
1238+ int num_dcache_entries;
1239+} intel_i810_private;
1240+
1241+static int intel_i810_fetch_size(void)
1242+{
1243+ u32 smram_miscc;
1244+ aper_size_info_fixed *values;
1245+
1246+ pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
1247+ values = (aper_size_info_fixed *) agp_bridge.aperture_sizes;
1248+
1249+ if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
1250+ printk("agpgart: i810 is disabled\n");
1251+ return 0;
1252+ }
1253+ if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
1254+ agp_bridge.previous_size =
1255+ agp_bridge.current_size = (void *) (values + 1);
1256+ agp_bridge.aperture_size_idx = 1;
1257+ return values[1].size;
1258+ } else {
1259+ agp_bridge.previous_size =
1260+ agp_bridge.current_size = (void *) (values);
1261+ agp_bridge.aperture_size_idx = 0;
1262+ return values[0].size;
1263+ }
1264+
1265+ return 0;
1266+}
1267+
1268+static int intel_i810_configure(void)
1269+{
1270+ aper_size_info_fixed *current_size;
1271+ u32 temp;
1272+ int i;
1273+
1274+ current_size = (aper_size_info_fixed *) agp_bridge.current_size;
1275+
1276+ pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
1277+ temp &= 0xfff80000;
1278+
1279+ intel_i810_private.registers =
1280+ (volatile unsigned char *) ioremap(temp, 128 * 4096);
1281+
1282+ if ((INREG32(intel_i810_private.registers, I810_DRAM_CTL)
1283+ & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) {
1284+ /* This will need to be dynamically assigned */
1285+ printk("agpgart: detected 4MB dedicated video ram.\n");
1286+ intel_i810_private.num_dcache_entries = 1024;
1287+ }
1288+ pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
1289+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1290+ OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
1291+ agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
1292+ CACHE_FLUSH();
1293+
1294+ if (agp_bridge.needs_scratch_page == TRUE) {
1295+ for (i = 0; i < current_size->num_entries; i++) {
1296+ OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1297+ agp_bridge.scratch_page);
1298+ }
1299+ }
1300+ return 0;
1301+}
1302+
1303+static void intel_i810_cleanup(void)
1304+{
1305+ OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL, 0);
1306+ iounmap((void *) intel_i810_private.registers);
1307+}
1308+
1309+static void intel_i810_tlbflush(agp_memory * mem)
1310+{
1311+ return;
1312+}
1313+
1314+static void intel_i810_agp_enable(u32 mode)
1315+{
1316+ return;
1317+}
1318+
1319+static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
1320+ int type)
1321+{
1322+ int i, j, num_entries;
1323+ void *temp;
1324+
1325+ temp = agp_bridge.current_size;
1326+ num_entries = ((aper_size_info_fixed *) temp)->num_entries;
1327+
1328+ if ((pg_start + mem->page_count) > num_entries) {
1329+ return -EINVAL;
1330+ }
1331+ for (j = pg_start; j < (pg_start + mem->page_count); j++) {
1332+ if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
1333+ return -EBUSY;
1334+ }
1335+ }
1336+
1337+ if (type != 0 || mem->type != 0) {
1338+ if ((type == AGP_DCACHE_MEMORY) &&
1339+ (mem->type == AGP_DCACHE_MEMORY)) {
1340+ /* special insert */
1341+
1342+ for (i = pg_start; i < (pg_start + mem->page_count); i++) {
1343+ OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1344+ (i * 4096) | I810_PTE_LOCAL | I810_PTE_VALID);
1345+ }
1346+
1347+ agp_bridge.tlb_flush(mem);
1348+ return 0;
1349+ }
1350+ return -EINVAL;
1351+ }
1352+ if (mem->is_flushed == FALSE) {
1353+ CACHE_FLUSH();
1354+ mem->is_flushed = TRUE;
1355+ }
1356+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1357+ OUTREG32(intel_i810_private.registers,
1358+ I810_PTE_BASE + (j * 4), mem->memory[i]);
1359+ }
1360+
1361+ agp_bridge.tlb_flush(mem);
1362+ return 0;
1363+}
1364+
1365+static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
1366+ int type)
1367+{
1368+ int i;
1369+
1370+ for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1371+ OUTREG32(intel_i810_private.registers, I810_PTE_BASE + (i * 4),
1372+ agp_bridge.scratch_page);
1373+ }
1374+
1375+ agp_bridge.tlb_flush(mem);
1376+ return 0;
1377+}
1378+
1379+static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
1380+{
1381+ agp_memory *new;
1382+
1383+ if (type == AGP_DCACHE_MEMORY) {
1384+ if (pg_count != intel_i810_private.num_dcache_entries) {
1385+ return NULL;
1386+ }
1387+ new = agp_create_memory(1);
1388+
1389+ if (new == NULL) {
1390+ return NULL;
1391+ }
1392+ new->type = AGP_DCACHE_MEMORY;
1393+ new->page_count = pg_count;
1394+ new->num_scratch_pages = 0;
1395+ vfree(new->memory);
1396+ return new;
1397+ }
1398+ return NULL;
1399+}
1400+
1401+static void intel_i810_free_by_type(agp_memory * curr)
1402+{
1403+ agp_free_key(curr->key);
1404+ kfree(curr);
1405+}
1406+
1407+static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
1408+{
1409+ /* Type checking must be done elsewhere */
1410+ return addr | agp_bridge.masks[type].mask;
1411+}
1412+
1413+static void intel_i810_setup(struct pci_dev *i810_dev)
1414+{
1415+ intel_i810_private.i810_dev = i810_dev;
1416+
1417+ agp_bridge.masks = intel_i810_masks;
1418+ agp_bridge.num_of_masks = 2;
1419+ agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
1420+ agp_bridge.size_type = FIXED_APER_SIZE;
1421+ agp_bridge.num_aperture_sizes = 2;
1422+ agp_bridge.dev_private_data = (void *) &intel_i810_private;
1423+ agp_bridge.needs_scratch_page = TRUE;
1424+ agp_bridge.configure = intel_i810_configure;
1425+ agp_bridge.fetch_size = intel_i810_fetch_size;
1426+ agp_bridge.cleanup = intel_i810_cleanup;
1427+ agp_bridge.tlb_flush = intel_i810_tlbflush;
1428+ agp_bridge.mask_memory = intel_i810_mask_memory;
1429+ agp_bridge.agp_enable = intel_i810_agp_enable;
1430+#ifdef __SMP__
1431+ agp_bridge.cache_flush = smp_flush_cache;
1432+#else
1433+ agp_bridge.cache_flush = flush_cache;
1434+#endif
1435+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1436+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1437+ agp_bridge.insert_memory = intel_i810_insert_entries;
1438+ agp_bridge.remove_memory = intel_i810_remove_entries;
1439+ agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
1440+ agp_bridge.free_by_type = intel_i810_free_by_type;
1441+}
1442+
1443+#endif
1444+
1445+#ifdef AGP_BUILD_INTEL_GENERIC
1446+
1447+static int intel_fetch_size(void)
1448+{
1449+ int i;
1450+ u16 temp;
1451+ aper_size_info_16 *values;
1452+
1453+ pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
1454+ (void *) values = agp_bridge.aperture_sizes;
1455+
1456+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1457+ if (temp == values[i].size_value) {
1458+ agp_bridge.previous_size =
1459+ agp_bridge.current_size = (void *) (values + i);
1460+ agp_bridge.aperture_size_idx = i;
1461+ return values[i].size;
1462+ }
1463+ }
1464+
1465+ return 0;
1466+}
1467+
1468+static void intel_tlbflush(agp_memory * mem)
1469+{
1470+ pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
1471+ pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
1472+}
1473+
1474+static void intel_cleanup(void)
1475+{
1476+ u16 temp;
1477+
1478+ pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
1479+ pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
1480+}
1481+
1482+static int intel_configure(void)
1483+{
1484+ u32 temp;
1485+ u16 temp2;
1486+ aper_size_info_16 *current_size;
1487+
1488+ current_size = (aper_size_info_16 *) agp_bridge.current_size;
1489+
1490+ /* aperture size */
1491+ pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
1492+
1493+ /* address to map to */
1494+ pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
1495+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1496+
1497+ /* attbase - aperture base */
1498+ pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
1499+
1500+ /* agpctrl */
1501+ pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
1502+
1503+ /* paccfg/nbxcfg */
1504+ pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
1505+ pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, (temp2 & ~(1 << 10)) | (1 << 9));
1506+ /* clear any possible error conditions */
1507+ pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
1508+ return 0;
1509+}
1510+
1511+static unsigned long intel_mask_memory(unsigned long addr, int type)
1512+{
1513+ /* Memory type is ignored */
1514+
1515+ return addr | agp_bridge.masks[0].mask;
1516+}
1517+
1518+
1519+/* Setup function */
1520+static gatt_mask intel_generic_masks[] =
1521+{
1522+ {0x00000017, 0}
1523+};
1524+
1525+static aper_size_info_16 intel_generic_sizes[7] =
1526+{
1527+ {256, 65536, 6, 0},
1528+ {128, 32768, 5, 32},
1529+ {64, 16384, 4, 48},
1530+ {32, 8192, 3, 56},
1531+ {16, 4096, 2, 60},
1532+ {8, 2048, 1, 62},
1533+ {4, 1024, 0, 63}
1534+};
1535+
1536+static void intel_generic_setup(void)
1537+{
1538+ agp_bridge.masks = intel_generic_masks;
1539+ agp_bridge.num_of_masks = 1;
1540+ agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
1541+ agp_bridge.size_type = U16_APER_SIZE;
1542+ agp_bridge.num_aperture_sizes = 7;
1543+ agp_bridge.dev_private_data = NULL;
1544+ agp_bridge.needs_scratch_page = FALSE;
1545+ agp_bridge.configure = intel_configure;
1546+ agp_bridge.fetch_size = intel_fetch_size;
1547+ agp_bridge.cleanup = intel_cleanup;
1548+ agp_bridge.tlb_flush = intel_tlbflush;
1549+ agp_bridge.mask_memory = intel_mask_memory;
1550+ agp_bridge.agp_enable = agp_generic_agp_enable;
1551+#ifdef __SMP__
1552+ agp_bridge.cache_flush = smp_flush_cache;
1553+#else
1554+ agp_bridge.cache_flush = flush_cache;
1555+#endif
1556+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1557+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1558+ agp_bridge.insert_memory = agp_generic_insert_memory;
1559+ agp_bridge.remove_memory = agp_generic_remove_memory;
1560+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1561+ agp_bridge.free_by_type = agp_generic_free_by_type;
1562+}
1563+
1564+#endif
1565+
1566+#ifdef AGP_BUILD_VIA_GENERIC
1567+
1568+static int via_fetch_size(void)
1569+{
1570+ int i;
1571+ u8 temp;
1572+ aper_size_info_8 *values;
1573+
1574+ (void *) values = agp_bridge.aperture_sizes;
1575+ pci_read_config_byte(agp_bridge.dev, VIA_APSIZE, &temp);
1576+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1577+ if (temp == values[i].size_value) {
1578+ agp_bridge.previous_size =
1579+ agp_bridge.current_size = (void *) (values + i);
1580+ agp_bridge.aperture_size_idx = i;
1581+ return values[i].size;
1582+ }
1583+ }
1584+
1585+ return 0;
1586+}
1587+
1588+static int via_configure(void)
1589+{
1590+ u32 temp;
1591+ aper_size_info_8 *current_size;
1592+
1593+ current_size = (aper_size_info_8 *) agp_bridge.current_size;
1594+ /* aperture size */
1595+ pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, current_size->size_value);
1596+ /* address to map too */
1597+ pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp);
1598+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1599+
1600+ /* GART control register */
1601+ pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
1602+
1603+ /* attbase - aperture GATT base */
1604+ pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE,
1605+ (agp_bridge.gatt_bus_addr & 0xfffff000) | 3);
1606+ return 0;
1607+}
1608+
1609+static void via_cleanup(void)
1610+{
1611+ aper_size_info_8 *previous_size;
1612+
1613+ previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
1614+ pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE, 0);
1615+ pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, previous_size->size_value);
1616+}
1617+
1618+static void via_tlbflush(agp_memory * mem)
1619+{
1620+ pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000008f);
1621+ pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
1622+}
1623+
1624+static unsigned long via_mask_memory(unsigned long addr, int type)
1625+{
1626+ /* Memory type is ignored */
1627+
1628+ return addr | agp_bridge.masks[0].mask;
1629+}
1630+
1631+static aper_size_info_8 via_generic_sizes[7] =
1632+{
1633+ {256, 65536, 6, 0},
1634+ {128, 32768, 5, 128},
1635+ {64, 16384, 4, 192},
1636+ {32, 8192, 3, 224},
1637+ {16, 4096, 2, 240},
1638+ {8, 2048, 1, 248},
1639+ {4, 1024, 0, 252}
1640+};
1641+
1642+static gatt_mask via_generic_masks[] =
1643+{
1644+ {0x00000000, 0}
1645+};
1646+
1647+static void via_generic_setup(void)
1648+{
1649+ agp_bridge.masks = via_generic_masks;
1650+ agp_bridge.num_of_masks = 1;
1651+ agp_bridge.aperture_sizes = (void *) via_generic_sizes;
1652+ agp_bridge.size_type = U8_APER_SIZE;
1653+ agp_bridge.num_aperture_sizes = 7;
1654+ agp_bridge.dev_private_data = NULL;
1655+ agp_bridge.needs_scratch_page = FALSE;
1656+ agp_bridge.configure = via_configure;
1657+ agp_bridge.fetch_size = via_fetch_size;
1658+ agp_bridge.cleanup = via_cleanup;
1659+ agp_bridge.tlb_flush = via_tlbflush;
1660+ agp_bridge.mask_memory = via_mask_memory;
1661+ agp_bridge.agp_enable = agp_generic_agp_enable;
1662+#ifdef __SMP__
1663+ agp_bridge.cache_flush = smp_flush_cache;
1664+#else
1665+ agp_bridge.cache_flush = flush_cache;
1666+#endif
1667+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1668+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1669+ agp_bridge.insert_memory = agp_generic_insert_memory;
1670+ agp_bridge.remove_memory = agp_generic_remove_memory;
1671+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1672+ agp_bridge.free_by_type = agp_generic_free_by_type;
1673+}
1674+
1675+#endif
1676+
1677+#ifdef AGP_BUILD_SIS_GENERIC
1678+
1679+static int sis_fetch_size(void)
1680+{
1681+ u8 temp_size;
1682+ int i;
1683+ aper_size_info_8 *values;
1684+
1685+ pci_read_config_byte(agp_bridge.dev, SIS_APSIZE, &temp_size);
1686+ (void *) values = agp_bridge.aperture_sizes;
1687+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1688+ if ((temp_size == values[i].size_value) ||
1689+ ((temp_size & ~(0x03)) == (values[i].size_value & ~(0x03)))) {
1690+ agp_bridge.previous_size =
1691+ agp_bridge.current_size = (void *) (values + i);
1692+
1693+ agp_bridge.aperture_size_idx = i;
1694+ return values[i].size;
1695+ }
1696+ }
1697+
1698+ return 0;
1699+}
1700+
1701+
1702+static void sis_tlbflush(agp_memory * mem)
1703+{
1704+ pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02);
1705+}
1706+
1707+static int sis_configure(void)
1708+{
1709+ u32 temp;
1710+ aper_size_info_8 *current_size;
1711+
1712+ current_size = (aper_size_info_8 *) agp_bridge.current_size;
1713+ pci_write_config_byte(agp_bridge.dev, SIS_TLBCNTRL, 0x05);
1714+ pci_read_config_dword(agp_bridge.dev, SIS_APBASE, &temp);
1715+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1716+ pci_write_config_dword(agp_bridge.dev, SIS_ATTBASE, agp_bridge.gatt_bus_addr);
1717+ pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, current_size->size_value);
1718+ return 0;
1719+}
1720+
1721+static void sis_cleanup(void)
1722+{
1723+ aper_size_info_8 *previous_size;
1724+
1725+ previous_size = (aper_size_info_8 *) agp_bridge.previous_size;
1726+ pci_write_config_byte(agp_bridge.dev, SIS_APSIZE, (previous_size->size_value & ~(0x03)));
1727+}
1728+
1729+static unsigned long sis_mask_memory(unsigned long addr, int type)
1730+{
1731+ /* Memory type is ignored */
1732+
1733+ return addr | agp_bridge.masks[0].mask;
1734+}
1735+
1736+static aper_size_info_8 sis_generic_sizes[7] =
1737+{
1738+ {256, 65536, 6, 99},
1739+ {128, 32768, 5, 83},
1740+ {64, 16384, 4, 67},
1741+ {32, 8192, 3, 51},
1742+ {16, 4096, 2, 35},
1743+ {8, 2048, 1, 19},
1744+ {4, 1024, 0, 3}
1745+};
1746+
1747+static gatt_mask sis_generic_masks[] =
1748+{
1749+ {0x00000000, 0}
1750+};
1751+
1752+static void sis_generic_setup(void)
1753+{
1754+ agp_bridge.masks = sis_generic_masks;
1755+ agp_bridge.num_of_masks = 1;
1756+ agp_bridge.aperture_sizes = (void *) sis_generic_sizes;
1757+ agp_bridge.size_type = U8_APER_SIZE;
1758+ agp_bridge.num_aperture_sizes = 7;
1759+ agp_bridge.dev_private_data = NULL;
1760+ agp_bridge.needs_scratch_page = FALSE;
1761+ agp_bridge.configure = sis_configure;
1762+ agp_bridge.fetch_size = sis_fetch_size;
1763+ agp_bridge.cleanup = sis_cleanup;
1764+ agp_bridge.tlb_flush = sis_tlbflush;
1765+ agp_bridge.mask_memory = sis_mask_memory;
1766+ agp_bridge.agp_enable = agp_generic_agp_enable;
1767+#ifdef __SMP__
1768+ agp_bridge.cache_flush = smp_flush_cache;
1769+#else
1770+ agp_bridge.cache_flush = flush_cache;
1771+#endif
1772+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1773+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1774+ agp_bridge.insert_memory = agp_generic_insert_memory;
1775+ agp_bridge.remove_memory = agp_generic_remove_memory;
1776+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1777+ agp_bridge.free_by_type = agp_generic_free_by_type;
1778+}
1779+
1780+#endif
1781+
1782+#ifdef AGP_BUILD_AMD_IRONGATE
1783+
1784+static struct _amd_irongate_private {
1785+ volatile unsigned char *registers;
1786+} amd_irongate_private;
1787+
1788+static int amd_irongate_fetch_size(void)
1789+{
1790+ int i;
1791+ u32 temp;
1792+ aper_size_info_32 *values;
1793+
1794+ pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1795+ temp = (temp & 0x0000000e);
1796+ (void *) values = agp_bridge.aperture_sizes;
1797+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1798+ if (temp == values[i].size_value) {
1799+ agp_bridge.previous_size =
1800+ agp_bridge.current_size = (void *) (values + i);
1801+
1802+ agp_bridge.aperture_size_idx = i;
1803+ return values[i].size;
1804+ }
1805+ }
1806+
1807+ return 0;
1808+}
1809+
1810+static int amd_irongate_configure(void)
1811+{
1812+ aper_size_info_32 *current_size;
1813+ u32 temp;
1814+ u16 enable_reg;
1815+
1816+ current_size = (aper_size_info_32 *) agp_bridge.current_size;
1817+
1818+ /* Get the memory mapped registers */
1819+ pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
1820+ temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1821+ amd_irongate_private.registers = (volatile unsigned char *) ioremap(temp, 4096);
1822+
1823+ /* Write out the address of the gatt table */
1824+ OUTREG32(amd_irongate_private.registers, AMD_ATTBASE, agp_bridge.gatt_bus_addr);
1825+
1826+ /* Write the Sync register */
1827+ pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
1828+
1829+ /* Write the enable register */
1830+ enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
1831+ enable_reg = (enable_reg | 0x0004);
1832+ OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
1833+
1834+ /* Write out the size register */
1835+ pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1836+ temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 0x00000001);
1837+ pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
1838+
1839+ /* Flush the tlb */
1840+ OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
1841+
1842+ /* Get the address for the gart region */
1843+ pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
1844+ temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1845+ agp_bridge.gart_bus_addr = temp;
1846+ return 0;
1847+}
1848+
1849+static void amd_irongate_cleanup(void)
1850+{
1851+ aper_size_info_32 *previous_size;
1852+ u32 temp;
1853+ u16 enable_reg;
1854+
1855+ previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
1856+
1857+ enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
1858+ enable_reg = (enable_reg & ~(0x0004));
1859+ OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
1860+
1861+ /* Write back the previous size and disable gart translation */
1862+ pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
1863+ temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
1864+ pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
1865+ iounmap((void *) amd_irongate_private.registers);
1866+}
1867+
1868+/*
1869+ * This routine could be implemented by taking the addresses
1870+ * written to the GATT, and flushing them individually. However
1871+ * currently it just flushes the whole table. Which is probably
1872+ * more efficent, since agp_memory blocks can be a large number of
1873+ * entries.
1874+ */
1875+
1876+static void amd_irongate_tlbflush(agp_memory * temp)
1877+{
1878+ OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
1879+}
1880+
1881+static unsigned long amd_irongate_mask_memory(unsigned long addr, int type)
1882+{
1883+ /* Only type 0 is supported by the irongate */
1884+
1885+ return addr | agp_bridge.masks[0].mask;
1886+}
1887+
1888+static aper_size_info_32 amd_irongate_sizes[7] =
1889+{
1890+ {2048, 524288, 9, 0x0000000c},
1891+ {1024, 262144, 8, 0x0000000a},
1892+ {512, 131072, 7, 0x00000008},
1893+ {256, 65536, 6, 0x00000006},
1894+ {128, 32768, 5, 0x00000004},
1895+ {64, 16384, 4, 0x00000002},
1896+ {32, 8192, 3, 0x00000000}
1897+};
1898+
1899+static gatt_mask amd_irongate_masks[] =
1900+{
1901+ {0x00000001, 0}
1902+};
1903+
1904+static void amd_irongate_setup(void)
1905+{
1906+ agp_bridge.masks = amd_irongate_masks;
1907+ agp_bridge.num_of_masks = 1;
1908+ agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
1909+ agp_bridge.size_type = U32_APER_SIZE;
1910+ agp_bridge.num_aperture_sizes = 7;
1911+ agp_bridge.dev_private_data = (void *) &amd_irongate_private;
1912+ agp_bridge.needs_scratch_page = FALSE;
1913+ agp_bridge.configure = amd_irongate_configure;
1914+ agp_bridge.fetch_size = amd_irongate_fetch_size;
1915+ agp_bridge.cleanup = amd_irongate_cleanup;
1916+ agp_bridge.tlb_flush = amd_irongate_tlbflush;
1917+ agp_bridge.mask_memory = amd_irongate_mask_memory;
1918+ agp_bridge.agp_enable = agp_generic_agp_enable;
1919+#ifdef __SMP__
1920+ agp_bridge.cache_flush = smp_flush_cache;
1921+#else
1922+ agp_bridge.cache_flush = flush_cache;
1923+#endif
1924+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
1925+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
1926+ agp_bridge.insert_memory = agp_generic_insert_memory;
1927+ agp_bridge.remove_memory = agp_generic_remove_memory;
1928+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
1929+ agp_bridge.free_by_type = agp_generic_free_by_type;
1930+}
1931+
1932+#endif
1933+
1934+#ifdef AGP_BUILD_ALI_M1541
1935+
1936+static int ali_fetch_size(void)
1937+{
1938+ int i;
1939+ u32 temp;
1940+ aper_size_info_32 *values;
1941+
1942+ pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp);
1943+ temp &= ~(0xfffffff0);
1944+ (void *) values = agp_bridge.aperture_sizes;
1945+
1946+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
1947+ if (temp == values[i].size_value) {
1948+ agp_bridge.previous_size =
1949+ agp_bridge.current_size = (void *) (values + i);
1950+ agp_bridge.aperture_size_idx = i;
1951+ return values[i].size;
1952+ }
1953+ }
1954+
1955+ return 0;
1956+}
1957+
1958+static void ali_tlbflush(agp_memory * mem)
1959+{
1960+ u32 temp;
1961+
1962+ pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1963+ pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1964+ ((temp & 0xffffff00) | 0x00000090));
1965+ pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1966+ ((temp & 0xffffff00) | 0x00000010));
1967+}
1968+
1969+static void ali_cleanup(void)
1970+{
1971+ aper_size_info_32 *previous_size;
1972+ u32 temp;
1973+
1974+ previous_size = (aper_size_info_32 *) agp_bridge.previous_size;
1975+
1976+ pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1977+ pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1978+ ((temp & 0xffffff00) | 0x00000090));
1979+ pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, previous_size->size_value);
1980+}
1981+
1982+static int ali_configure(void)
1983+{
1984+ u32 temp;
1985+ aper_size_info_32 *current_size;
1986+
1987+ current_size = (aper_size_info_32 *) agp_bridge.current_size;
1988+
1989+ /* aperture size and gatt addr */
1990+ pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE,
1991+ agp_bridge.gatt_bus_addr | current_size->size_value);
1992+
1993+ /* tlb control */
1994+ pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
1995+ pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL,
1996+ ((temp & 0xffffff00) | 0x00000010));
1997+
1998+ /* address to map to */
1999+ pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
2000+ agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
2001+ return 0;
2002+}
2003+
2004+static unsigned long ali_mask_memory(unsigned long addr, int type)
2005+{
2006+ /* Memory type is ignored */
2007+
2008+ return addr | agp_bridge.masks[0].mask;
2009+}
2010+
2011+
2012+/* Setup function */
2013+static gatt_mask ali_generic_masks[] =
2014+{
2015+ {0x00000000, 0}
2016+};
2017+
2018+static aper_size_info_32 ali_generic_sizes[7] =
2019+{
2020+ {256, 65536, 6, 10},
2021+ {128, 32768, 5, 9},
2022+ {64, 16384, 4, 8},
2023+ {32, 8192, 3, 7},
2024+ {16, 4096, 2, 6},
2025+ {8, 2048, 1, 4},
2026+ {4, 1024, 0, 3}
2027+};
2028+
2029+static void ali_generic_setup(void)
2030+{
2031+ agp_bridge.masks = ali_generic_masks;
2032+ agp_bridge.num_of_masks = 1;
2033+ agp_bridge.aperture_sizes = (void *) ali_generic_sizes;
2034+ agp_bridge.size_type = U32_APER_SIZE;
2035+ agp_bridge.num_aperture_sizes = 7;
2036+ agp_bridge.dev_private_data = NULL;
2037+ agp_bridge.needs_scratch_page = FALSE;
2038+ agp_bridge.configure = ali_configure;
2039+ agp_bridge.fetch_size = ali_fetch_size;
2040+ agp_bridge.cleanup = ali_cleanup;
2041+ agp_bridge.tlb_flush = ali_tlbflush;
2042+ agp_bridge.mask_memory = ali_mask_memory;
2043+ agp_bridge.agp_enable = agp_generic_agp_enable;
2044+#ifdef __SMP__
2045+ agp_bridge.cache_flush = smp_flush_cache;
2046+#else
2047+ agp_bridge.cache_flush = flush_cache;
2048+#endif
2049+ agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
2050+ agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
2051+ agp_bridge.insert_memory = agp_generic_insert_memory;
2052+ agp_bridge.remove_memory = agp_generic_remove_memory;
2053+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
2054+ agp_bridge.free_by_type = agp_generic_free_by_type;
2055+}
2056+
2057+#endif
2058+
2059+
2060+
2061+/* Supported Device Scanning routine */
2062+
2063+static void agp_find_supported_device(void)
2064+{
2065+ struct pci_dev *dev = NULL;
2066+ u8 cap_ptr = 0x00;
2067+ u32 cap_id, scratch;
2068+
2069+ if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL) {
2070+ agp_bridge.type = NOT_SUPPORTED;
2071+ return;
2072+ }
2073+ agp_bridge.dev = dev;
2074+
2075+ /* Need to test for I810 here */
2076+#ifdef AGP_BUILD_INTEL_I810
2077+ if (dev->vendor == PCI_VENDOR_ID_INTEL) {
2078+ struct pci_dev *i810_dev;
2079+
2080+ switch (dev->device) {
2081+ case PCI_DEVICE_ID_INTEL_810_0:
2082+ i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2083+ PCI_DEVICE_ID_INTEL_810_1,
2084+ NULL);
2085+ if (i810_dev == NULL) {
2086+ printk("agpgart: Detected an Intel i810, but could not find the secondary device.\n");
2087+ agp_bridge.type = NOT_SUPPORTED;
2088+ return;
2089+ }
2090+ printk("agpgart: Detected an Intel i810 Chipset.\n");
2091+ agp_bridge.type = INTEL_I810;
2092+ agp_bridge.intel_i810_setup(i810_dev);
2093+ return;
2094+
2095+ case PCI_DEVICE_ID_INTEL_810_DC100_0:
2096+ i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2097+ PCI_DEVICE_ID_INTEL_810_DC100_1,
2098+ NULL);
2099+ if (i810_dev == NULL) {
2100+ printk("agpgart: Detected an Intel i810 DC100, but could not find the secondary device.\n");
2101+ agp_bridge.type = NOT_SUPPORTED;
2102+ return;
2103+ }
2104+ printk("agpgart: Detected an Intel i810 DC100 Chipset.\n");
2105+ agp_bridge.type = INTEL_I810;
2106+ agp_bridge.intel_i810_setup(i810_dev);
2107+ return;
2108+
2109+ case PCI_DEVICE_ID_INTEL_810_E_0:
2110+ i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
2111+ PCI_DEVICE_ID_INTEL_810_E_1,
2112+ NULL);
2113+ if (i810_dev == NULL) {
2114+ printk("agpgart: Detected an Intel i810 E, but could not find the secondary device.\n");
2115+ agp_bridge.type = NOT_SUPPORTED;
2116+ return;
2117+ }
2118+ printk("agpgart: Detected an Intel i810 E Chipset.\n");
2119+ agp_bridge.type = INTEL_I810;
2120+ agp_bridge.intel_i810_setup(i810_dev);
2121+ return;
2122+ default:
2123+ break;
2124+ }
2125+ }
2126+#endif
2127+ /* find capndx */
2128+ pci_read_config_dword(dev, 0x04, &scratch);
2129+
2130+ if (!(scratch & 0x00100000)) {
2131+ agp_bridge.type = NOT_SUPPORTED;
2132+ return;
2133+ }
2134+ pci_read_config_byte(dev, 0x34, &cap_ptr);
2135+
2136+ if (cap_ptr != 0x00) {
2137+ do {
2138+ pci_read_config_dword(dev, cap_ptr, &cap_id);
2139+
2140+ if ((cap_id & 0xff) != 0x02)
2141+ cap_ptr = (cap_id >> 8) & 0xff;
2142+ }
2143+ while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
2144+ }
2145+ if (cap_ptr == 0x00) {
2146+ agp_bridge.type = NOT_SUPPORTED;
2147+ return;
2148+ }
2149+ agp_bridge.capndx = cap_ptr;
2150+
2151+ /* Fill in the mode register */
2152+ pci_read_config_dword(agp_bridge.dev,
2153+ agp_bridge.capndx + 4,
2154+ &agp_bridge.mode);
2155+
2156+ switch (dev->vendor) {
2157+#ifdef AGP_BUILD_INTEL_GENERIC
2158+ case PCI_VENDOR_ID_INTEL:
2159+ switch (dev->device) {
2160+ case PCI_DEVICE_ID_INTEL_82443LX_0:
2161+ agp_bridge.type = INTEL_LX;
2162+ printk("agpgart: Detected an Intel 440LX Chipset.\n");
2163+ agp_bridge.intel_generic_setup();
2164+ return;
2165+
2166+ case PCI_DEVICE_ID_INTEL_82443BX_0:
2167+ agp_bridge.type = INTEL_BX;
2168+ printk("agpgart: Detected an Intel 440BX Chipset.\n");
2169+ agp_bridge.intel_generic_setup();
2170+ return;
2171+
2172+ case PCI_DEVICE_ID_INTEL_82443GX_0:
2173+ agp_bridge.type = INTEL_GX;
2174+ printk("agpgart: Detected an Intel 440GX Chipset.\n");
2175+ agp_bridge.intel_generic_setup();
2176+ return;
2177+
2178+ default:
2179+ if (agp_try_unsupported != 0) {
2180+ printk("agpgart: Trying generic intel routines for device id: %x\n", dev->device);
2181+ agp_bridge.type = INTEL_GENERIC;
2182+ agp_bridge.intel_generic_setup();
2183+ return;
2184+ } else {
2185+ printk("agpgart: Unsupported intel chipset, you might want to try agp_try_unsupported=1.\n");
2186+ agp_bridge.type = NOT_SUPPORTED;
2187+ return;
2188+ }
2189+ }
2190+ break;
2191+#endif
2192+
2193+#ifdef AGP_BUILD_VIA_GENERIC
2194+ case PCI_VENDOR_ID_VIA:
2195+ switch (dev->device) {
2196+ case PCI_DEVICE_ID_VIA_82C597_0:
2197+ agp_bridge.type = VIA_VP3;
2198+ printk("agpgart: Detected a VIA VP3 Chipset.\n");
2199+ agp_bridge.via_generic_setup();
2200+ return;
2201+
2202+ case PCI_DEVICE_ID_VIA_82C598_0:
2203+ agp_bridge.type = VIA_MVP3;
2204+ printk("agpgart: Detected a VIA MVP3 Chipset.\n");
2205+ agp_bridge.via_generic_setup();
2206+ return;
2207+
2208+ case PCI_DEVICE_ID_VIA_82C691_0:
2209+ agp_bridge.type = VIA_APOLLO_PRO;
2210+ printk("agpgart: Detected a VIA Apollo Pro Chipset.\n");
2211+ agp_bridge.via_generic_setup();
2212+ return;
2213+
2214+ default:
2215+ if (agp_try_unsupported != 0) {
2216+ printk("agpgart: Trying generic VIA routines for device id: %x\n", dev->device);
2217+ agp_bridge.type = VIA_GENERIC;
2218+ agp_bridge.via_generic_setup();
2219+ return;
2220+ } else {
2221+ printk("agpgart: Unsupported VIA chipset, you might want to try agp_try_unsupported=1.\n");
2222+ agp_bridge.type = NOT_SUPPORTED;
2223+ return;
2224+ }
2225+ }
2226+ break;
2227+#endif
2228+
2229+#ifdef AGP_BUILD_SIS_GENERIC
2230+ case PCI_VENDOR_ID_SI:
2231+ switch (dev->device) {
2232+ /* ToDo need to find out the specific devices supported */
2233+ default:
2234+ if (agp_try_unsupported != 0) {
2235+ printk("agpgart: Trying generic SiS routines for device id: %x\n", dev->device);
2236+ agp_bridge.type = SIS_GENERIC;
2237+ agp_bridge.sis_generic_setup();
2238+ return;
2239+ } else {
2240+ printk("agpgart: Unsupported SiS chipset, you might want to try agp_try_unsupported=1.\n");
2241+ agp_bridge.type = NOT_SUPPORTED;
2242+ return;
2243+ }
2244+ }
2245+ break;
2246+#endif
2247+
2248+#ifdef AGP_BUILD_AMD_IRONGATE
2249+ case PCI_VENDOR_ID_AMD:
2250+ switch (dev->device) {
2251+ case PCI_DEVICE_ID_AMD_IRONGATE_0:
2252+ agp_bridge.type = AMD_IRONGATE;
2253+ printk("agpgart: Detected an AMD Irongate Chipset.\n");
2254+ agp_bridge.amd_irongate_setup();
2255+ return;
2256+
2257+ default:
2258+ if (agp_try_unsupported != 0) {
2259+ printk("agpgart: Trying Amd irongate routines for device id: %x\n", dev->device);
2260+ agp_bridge.type = AMD_GENERIC;
2261+ agp_bridge.amd_irongate_setup();
2262+ return;
2263+ } else {
2264+ printk("agpgart: Unsupported Amd chipset, you might want to try agp_try_unsupported=1.\n");
2265+ agp_bridge.type = NOT_SUPPORTED;
2266+ return;
2267+ }
2268+ }
2269+ break;
2270+#endif
2271+
2272+#ifdef AGP_BUILD_ALI_M1541
2273+ case PCI_VENDOR_ID_AL:
2274+ switch (dev->device) {
2275+ case PCI_DEVICE_ID_AL_M1541_0:
2276+ agp_bridge.type = ALI_M1541;
2277+ printk("agpgart: Detected an ALi M1541 Chipset\n");
2278+ agp_bridge.ali_generic_setup();
2279+ return;
2280+ default:
2281+ if (agp_try_unsupported != 0) {
2282+ printk("agpgart: Trying ALi generic routines for device id: %x\n", dev->device);
2283+ agp_bridge.type = ALI_GENERIC;
2284+ agp_bridge.ali_generic_setup();
2285+ return;
2286+ } else {
2287+ printk("agpgart: Unsupported ALi chipset, you might want to type agp_try_unsupported=1.\n");
2288+ agp_bridge.type = NOT_SUPPORTED;
2289+ return;
2290+ }
2291+ }
2292+ break;
2293+#endif
2294+ default:
2295+ agp_bridge.type = NOT_SUPPORTED;
2296+ return;
2297+ }
2298+}
2299+
2300+struct agp_max_table {
2301+ int mem;
2302+ int agp;
2303+};
2304+
2305+static struct agp_max_table agp_maxes_table[9] =
2306+{
2307+ {0, 0},
2308+ {32, 4},
2309+ {64, 28},
2310+ {128, 96},
2311+ {256, 204},
2312+ {512, 440},
2313+ {1024, 942},
2314+ {2048, 1920},
2315+ {4096, 3932}
2316+};
2317+
2318+static int agp_find_max(void)
2319+{
2320+ int memory;
2321+ float t;
2322+ int index;
2323+ int result;
2324+
2325+ memory = virt_to_phys(high_memory) / 0x100000;
2326+ index = 0;
2327+
2328+ while ((memory > agp_maxes_table[index].mem) &&
2329+ (index < 8)) {
2330+ index++;
2331+ }
2332+
2333+ t = (memory - agp_maxes_table[index - 1].mem) /
2334+ (agp_maxes_table[index].mem - agp_maxes_table[index - 1].mem);
2335+
2336+ result = agp_maxes_table[index - 1].agp +
2337+ (t * (agp_maxes_table[index].agp - agp_maxes_table[index - 1].agp));
2338+
2339+ printk("agpgart: Maximum main memory to use for agp memory: %dM\n", result);
2340+ result = (result * 0x100000) / 4096;
2341+ return result;
2342+}
2343+
2344+#define AGPGART_VERSION_MAJOR 0
2345+#define AGPGART_VERSION_MINOR 99
2346+
2347+static agp_version agp_current_version =
2348+{
2349+ AGPGART_VERSION_MAJOR,
2350+ AGPGART_VERSION_MINOR
2351+};
2352+
2353+static int agp_backend_initialize(void)
2354+{
2355+ int size_value;
2356+
2357+ memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
2358+ agp_bridge.type = NOT_SUPPORTED;
2359+#ifdef AGP_BUILD_INTEL_GENERIC
2360+ agp_bridge.intel_generic_setup = intel_generic_setup;
2361+#endif
2362+#ifdef AGP_BUILD_INTEL_I810
2363+ agp_bridge.intel_i810_setup = intel_i810_setup;
2364+#endif
2365+#ifdef AGP_BUILD_VIA_GENERIC
2366+ agp_bridge.via_generic_setup = via_generic_setup;
2367+#endif
2368+#ifdef AGP_BUILD_SIS_GENERIC
2369+ agp_bridge.sis_generic_setup = sis_generic_setup;
2370+#endif
2371+#ifdef AGP_BUILD_AMD_IRONGATE
2372+ agp_bridge.amd_irongate_setup = amd_irongate_setup;
2373+#endif
2374+#ifdef AGP_BUILD_ALI_M1541
2375+ agp_bridge.ali_generic_setup = ali_generic_setup;
2376+#endif
2377+ agp_bridge.max_memory_agp = agp_find_max();
2378+ agp_bridge.version = &agp_current_version;
2379+ agp_find_supported_device();
2380+
2381+ if (agp_bridge.needs_scratch_page == TRUE) {
2382+ agp_bridge.scratch_page = (unsigned long) agp_alloc_page();
2383+
2384+ if ((void *) (agp_bridge.scratch_page) == NULL) {
2385+ printk("agpgart: unable to get memory for scratch page.\n");
2386+ return -ENOMEM;
2387+ }
2388+ agp_bridge.scratch_page = virt_to_phys((void *) agp_bridge.scratch_page);
2389+ agp_bridge.scratch_page = agp_bridge.mask_memory(agp_bridge.scratch_page, 0);
2390+ }
2391+ if (agp_bridge.type == NOT_SUPPORTED) {
2392+ printk("agpgart: no supported devices found.\n");
2393+ return -EINVAL;
2394+ }
2395+ size_value = agp_bridge.fetch_size();
2396+
2397+ if (size_value == 0) {
2398+ printk("agpgart: unable to detrimine aperture size.\n");
2399+ return -EINVAL;
2400+ }
2401+ if (agp_bridge.create_gatt_table()) {
2402+ printk("agpgart: unable to get memory for graphics translation table.\n");
2403+ return -ENOMEM;
2404+ }
2405+ agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
2406+
2407+ if (agp_bridge.key_list == NULL) {
2408+ printk("agpgart: error allocating memory for key lists.\n");
2409+ agp_bridge.free_gatt_table();
2410+ return -ENOMEM;
2411+ }
2412+ memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
2413+
2414+ if (agp_bridge.configure()) {
2415+ printk("agpgart: error configuring host chipset.\n");
2416+ agp_bridge.free_gatt_table();
2417+ vfree(agp_bridge.key_list);
2418+ return -EINVAL;
2419+ }
2420+ printk("agpgart: Physical address of the agp aperture: 0x%lx\n", agp_bridge.gart_bus_addr);
2421+ printk("agpgart: Agp aperture is %dM in size.\n", size_value);
2422+ return 0;
2423+}
2424+
2425+static void agp_backend_cleanup(void)
2426+{
2427+ agp_bridge.cleanup();
2428+ agp_bridge.free_gatt_table();
2429+ vfree(agp_bridge.key_list);
2430+
2431+ if (agp_bridge.needs_scratch_page == TRUE) {
2432+ agp_bridge.scratch_page &= ~(0x00000fff);
2433+ agp_destroy_page((void *) phys_to_virt(agp_bridge.scratch_page));
2434+ }
2435+}
2436+
2437+extern int agp_frontend_initialize(void);
2438+extern void agp_frontend_cleanup(void);
2439+
2440+#ifdef MODULE
2441+int init_module(void)
2442+{
2443+ int ret_val;
2444+
2445+ printk("Linux agpgart interface v%d.%d (c) Jeff Hartmann\n",
2446+ AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
2447+ ret_val = agp_backend_initialize();
2448+
2449+ if (ret_val != 0) {
2450+ return ret_val;
2451+ }
2452+ ret_val = agp_frontend_initialize();
2453+
2454+ if (ret_val != 0) {
2455+ agp_backend_cleanup();
2456+ return ret_val;
2457+ }
2458+ return 0;
2459+}
2460+
2461+void cleanup_module(void)
2462+{
2463+ agp_frontend_cleanup();
2464+ agp_backend_cleanup();
2465+}
2466+
2467+#endif
2468--- linux/drivers/char/agp/agp_backendP.h.newagpdist Fri Feb 11 14:50:45 2000
2469+++ linux/drivers/char/agp/agp_backendP.h Fri Feb 11 14:50:45 2000
2470@@ -0,0 +1,244 @@
2471+/*
2472+ * AGPGART module version 0.99
2473+ * Copyright (C) 1999 Jeff Hartmann
2474+ * Copyright (C) 1999 Precision Insight
2475+ * Copyright (C) 1999 Xi Graphics
2476+ *
2477+ * Permission is hereby granted, free of charge, to any person obtaining a
2478+ * copy of this software and associated documentation files (the "Software"),
2479+ * to deal in the Software without restriction, including without limitation
2480+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
2481+ * and/or sell copies of the Software, and to permit persons to whom the
2482+ * Software is furnished to do so, subject to the following conditions:
2483+ *
2484+ * The above copyright notice and this permission notice shall be included
2485+ * in all copies or substantial portions of the Software.
2486+ *
2487+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2488+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2489+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2490+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
2491+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2492+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
2493+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2494+ *
2495+ */
2496+
2497+#ifndef _AGP_BACKEND_PRIV_H
2498+#define _AGP_BACKEND_PRIV_H 1
2499+
2500+enum aper_size_type {
2501+ U8_APER_SIZE,
2502+ U16_APER_SIZE,
2503+ U32_APER_SIZE,
2504+ FIXED_APER_SIZE
2505+};
2506+
2507+typedef struct _gatt_mask {
2508+ unsigned long mask;
2509+ u32 type;
2510+ /* totally device specific, for integrated chipsets that
2511+ * might have different types of memory masks. For other
2512+ * devices this will probably be ignored */
2513+} gatt_mask;
2514+
2515+typedef struct _aper_size_info_8 {
2516+ int size;
2517+ int num_entries;
2518+ int page_order;
2519+ u8 size_value;
2520+} aper_size_info_8;
2521+
2522+typedef struct _aper_size_info_16 {
2523+ int size;
2524+ int num_entries;
2525+ int page_order;
2526+ u16 size_value;
2527+} aper_size_info_16;
2528+
2529+typedef struct _aper_size_info_32 {
2530+ int size;
2531+ int num_entries;
2532+ int page_order;
2533+ u32 size_value;
2534+} aper_size_info_32;
2535+
2536+typedef struct _aper_size_info_fixed {
2537+ int size;
2538+ int num_entries;
2539+ int page_order;
2540+} aper_size_info_fixed;
2541+
2542+struct agp_bridge_data {
2543+ agp_version *version;
2544+ void *aperture_sizes;
2545+ void *previous_size;
2546+ void *current_size;
2547+ void *dev_private_data;
2548+ struct pci_dev *dev;
2549+ gatt_mask *masks;
2550+ unsigned long *gatt_table;
2551+ unsigned long *gatt_table_real;
2552+ unsigned long scratch_page;
2553+ unsigned long gart_bus_addr;
2554+ unsigned long gatt_bus_addr;
2555+ u32 mode;
2556+ enum chipset_type type;
2557+ enum aper_size_type size_type;
2558+ u32 *key_list;
2559+ atomic_t current_memory_agp;
2560+ atomic_t agp_in_use;
2561+ int max_memory_agp; /* in number of pages */
2562+ int needs_scratch_page;
2563+ int aperture_size_idx;
2564+ int num_aperture_sizes;
2565+ int num_of_masks;
2566+ int capndx;
2567+
2568+ /* Links to driver specific functions */
2569+
2570+ int (*fetch_size) (void); /* returns the index into the size table */
2571+ int (*configure) (void);
2572+ void (*agp_enable) (u32);
2573+ void (*cleanup) (void);
2574+ void (*tlb_flush) (agp_memory *);
2575+ unsigned long (*mask_memory) (unsigned long, int);
2576+ void (*cache_flush) (void);
2577+ int (*create_gatt_table) (void);
2578+ int (*free_gatt_table) (void);
2579+ int (*insert_memory) (agp_memory *, off_t, int);
2580+ int (*remove_memory) (agp_memory *, off_t, int);
2581+ agp_memory *(*alloc_by_type) (size_t, int);
2582+ void (*free_by_type) (agp_memory *);
2583+
2584+ /* Links to vendor/device specific setup functions */
2585+#ifdef AGP_BUILD_INTEL_GENERIC
2586+ void (*intel_generic_setup) (void);
2587+#endif
2588+#ifdef AGP_BUILD_INTEL_I810
2589+ void (*intel_i810_setup) (struct pci_dev *);
2590+#endif
2591+#ifdef AGP_BUILD_VIA_GENERIC
2592+ void (*via_generic_setup) (void);
2593+#endif
2594+#ifdef AGP_BUILD_SIS_GENERIC
2595+ void (*sis_generic_setup) (void);
2596+#endif
2597+#ifdef AGP_BUILD_AMD_IRONGATE
2598+ void (*amd_irongate_setup) (void);
2599+#endif
2600+#ifdef AGP_BUILD_ALI_M1541
2601+ void (*ali_generic_setup) (void);
2602+#endif
2603+};
2604+
2605+#define OUTREG32(mmap, addr, val) *(volatile u32 *)(mmap + (addr)) = (val)
2606+#define OUTREG16(mmap, addr, val) *(volatile u16 *)(mmap + (addr)) = (val)
2607+#define OUTREG8 (mmap, addr, val) *(volatile u8 *) (mmap + (addr)) = (val)
2608+
2609+#define INREG32(mmap, addr) *(volatile u32 *)(mmap + (addr))
2610+#define INREG16(mmap, addr) *(volatile u16 *)(mmap + (addr))
2611+#define INREG8 (mmap, addr) *(volatile u8 *) (mmap + (addr))
2612+
2613+#ifndef min
2614+#define min(a,b) (((a)<(b))?(a):(b))
2615+#endif
2616+
2617+#define PGE_EMPTY(p) (!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
2618+
2619+#ifndef PCI_DEVICE_ID_VIA_82C691_0
2620+#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
2621+#endif
2622+#ifndef PCI_DEVICE_ID_VIA_82C691_1
2623+#define PCI_DEVICE_ID_VIA_82C691_1 0x8691
2624+#endif
2625+#ifndef PCI_DEVICE_ID_INTEL_810_0
2626+#define PCI_DEVICE_ID_INTEL_810_0 0x7120
2627+#endif
2628+#ifndef PCI_DEVICE_ID_INTEL_810_DC100_0
2629+#define PCI_DEVICE_ID_INTEL_810_DC100_0 0x7122
2630+#endif
2631+#ifndef PCI_DEVICE_ID_INTEL_810_E_0
2632+#define PCI_DEVICE_ID_INTEL_810_E_0 0x7124
2633+#endif
2634+#ifndef PCI_DEVICE_ID_INTEL_82443GX_0
2635+#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
2636+#endif
2637+#ifndef PCI_DEVICE_ID_INTEL_810_1
2638+#define PCI_DEVICE_ID_INTEL_810_1 0x7121
2639+#endif
2640+#ifndef PCI_DEVICE_ID_INTEL_810_DC100_1
2641+#define PCI_DEVICE_ID_INTEL_810_DC100_1 0x7123
2642+#endif
2643+#ifndef PCI_DEVICE_ID_INTEL_810_E_1
2644+#define PCI_DEVICE_ID_INTEL_810_E_1 0x7125
2645+#endif
2646+#ifndef PCI_DEVICE_ID_INTEL_82443GX_1
2647+#define PCI_DEVICE_ID_INTEL_82443GX_1 0x71a1
2648+#endif
2649+#ifndef PCI_DEVICE_ID_AMD_IRONGATE_0
2650+#define PCI_DEVICE_ID_AMD_IRONGATE_0 0x7006
2651+#endif
2652+#ifndef PCI_VENDOR_ID_AL
2653+#define PCI_VENDOR_ID_AL 0x10b9
2654+#endif
2655+#ifndef PCI_DEVICE_ID_AL_M1541_0
2656+#define PCI_DEVICE_ID_AL_M1541_0 0x1541
2657+#endif
2658+
2659+/* intel register */
2660+#define INTEL_APBASE 0x10
2661+#define INTEL_APSIZE 0xb4
2662+#define INTEL_ATTBASE 0xb8
2663+#define INTEL_AGPCTRL 0xb0
2664+#define INTEL_NBXCFG 0x50
2665+#define INTEL_ERRSTS 0x91
2666+
2667+/* intel i810 registers */
2668+#define I810_GMADDR 0x10
2669+#define I810_MMADDR 0x14
2670+#define I810_PTE_BASE 0x10000
2671+#define I810_PTE_MAIN_UNCACHED 0x00000000
2672+#define I810_PTE_LOCAL 0x00000002
2673+#define I810_PTE_VALID 0x00000001
2674+#define I810_SMRAM_MISCC 0x70
2675+#define I810_GFX_MEM_WIN_SIZE 0x00010000
2676+#define I810_GFX_MEM_WIN_32M 0x00010000
2677+#define I810_GMS 0x000000c0
2678+#define I810_GMS_DISABLE 0x00000000
2679+#define I810_PGETBL_CTL 0x2020
2680+#define I810_PGETBL_ENABLED 0x00000001
2681+#define I810_DRAM_CTL 0x3000
2682+#define I810_DRAM_ROW_0 0x00000001
2683+#define I810_DRAM_ROW_0_SDRAM 0x00000001
2684+
2685+/* VIA register */
2686+#define VIA_APBASE 0x10
2687+#define VIA_GARTCTRL 0x80
2688+#define VIA_APSIZE 0x84
2689+#define VIA_ATTBASE 0x88
2690+
2691+/* SiS registers */
2692+#define SIS_APBASE 0x10
2693+#define SIS_ATTBASE 0x90
2694+#define SIS_APSIZE 0x94
2695+#define SIS_TLBCNTRL 0x97
2696+#define SIS_TLBFLUSH 0x98
2697+
2698+/* AMD registers */
2699+#define AMD_APBASE 0x10
2700+#define AMD_MMBASE 0x14
2701+#define AMD_APSIZE 0xac
2702+#define AMD_MODECNTL 0xb0
2703+#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
2704+#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
2705+#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
2706+#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
2707+
2708+/* ALi registers */
2709+#define ALI_APBASE 0x10
2710+#define ALI_AGPCTRL 0xb8
2711+#define ALI_ATTBASE 0xbc
2712+#define ALI_TLBCTRL 0xc0
2713+
2714+#endif /* _AGP_BACKEND_PRIV_H */
2715--- linux/drivers/char/agp/agpgart_fe.c.newagpdist Fri Feb 11 14:50:45 2000
2716+++ linux/drivers/char/agp/agpgart_fe.c Fri Feb 11 14:50:45 2000
2717@@ -0,0 +1,1087 @@
2718+/*
2719+ * AGPGART module frontend version 0.99
2720+ * Copyright (C) 1999 Jeff Hartmann
2721+ * Copyright (C) 1999 Precision Insight
2722+ * Copyright (C) 1999 Xi Graphics
2723+ *
2724+ * Permission is hereby granted, free of charge, to any person obtaining a
2725+ * copy of this software and associated documentation files (the "Software"),
2726+ * to deal in the Software without restriction, including without limitation
2727+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
2728+ * and/or sell copies of the Software, and to permit persons to whom the
2729+ * Software is furnished to do so, subject to the following conditions:
2730+ *
2731+ * The above copyright notice and this permission notice shall be included
2732+ * in all copies or substantial portions of the Software.
2733+ *
2734+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2735+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2736+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2737+ * JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
2738+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2739+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
2740+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2741+ *
2742+ */
2743+
2744+#define __NO_VERSION__
2745+#include <linux/config.h>
2746+#include <linux/version.h>
2747+#include <linux/types.h>
2748+#include <linux/kernel.h>
2749+#include <linux/module.h>
2750+#include <linux/sched.h>
2751+#include <linux/mm.h>
2752+#include <linux/string.h>
2753+#include <linux/errno.h>
2754+#include <linux/malloc.h>
2755+#include <linux/vmalloc.h>
2756+#include <linux/pci.h>
2757+#include <linux/init.h>
2758+#include <linux/pagemap.h>
2759+#include <linux/miscdevice.h>
2760+#include <linux/agp_backend.h>
2761+#include <linux/agpgart.h>
2762+#include <asm/system.h>
2763+#include <asm/uaccess.h>
2764+#include <asm/system.h>
2765+#include <asm/io.h>
2766+#include <asm/page.h>
2767+#include <asm/mman.h>
2768+
2769+static struct agp_front_data agp_fe;
2770+
2771+static agp_memory *agp_find_mem_by_key(int key)
2772+{
2773+ agp_memory *curr;
2774+
2775+ if (agp_fe.current_controller == NULL) {
2776+ return NULL;
2777+ }
2778+ curr = agp_fe.current_controller->pool;
2779+
2780+ while (curr != NULL) {
2781+ if (curr->key == key) {
2782+ return curr;
2783+ }
2784+ curr = curr->next;
2785+ }
2786+
2787+ return NULL;
2788+}
2789+
2790+static void agp_remove_from_pool(agp_memory * temp)
2791+{
2792+ agp_memory *prev;
2793+ agp_memory *next;
2794+
2795+ /* Check to see if this is even in the memory pool */
2796+
2797+ if (agp_find_mem_by_key(temp->key) != NULL) {
2798+ next = temp->next;
2799+ prev = temp->prev;
2800+
2801+ if (prev != NULL) {
2802+ prev->next = next;
2803+ if (next != NULL) {
2804+ next->prev = prev;
2805+ }
2806+ } else {
2807+ /* This is the first item on the list */
2808+ if (next != NULL) {
2809+ next->prev = NULL;
2810+ }
2811+ agp_fe.current_controller->pool = next;
2812+ }
2813+ }
2814+}
2815+
2816+/*
2817+ * Routines for managing each client's segment list -
2818+ * These routines handle adding and removing segments
2819+ * to each auth'ed client.
2820+ */
2821+
2822+static agp_segment_priv *agp_find_seg_in_client(const agp_client * client,
2823+ unsigned long offset,
2824+ int size, pgprot_t page_prot)
2825+{
2826+ agp_segment_priv *seg;
2827+ int num_segments, pg_start, pg_count, i;
2828+
2829+ pg_start = offset / 4096;
2830+ pg_count = size / 4096;
2831+ seg = *(client->segments);
2832+ num_segments = client->num_segments;
2833+
2834+ for (i = 0; i < client->num_segments; i++) {
2835+ if ((seg[i].pg_start == pg_start) &&
2836+ (seg[i].pg_count == pg_count) &&
2837+ (pgprot_val(seg[i].prot) == pgprot_val(page_prot))) {
2838+ return seg + i;
2839+ }
2840+ }
2841+
2842+ return NULL;
2843+}
2844+
2845+static void agp_remove_seg_from_client(agp_client * client)
2846+{
2847+ if (client->segments != NULL) {
2848+ if (*(client->segments) != NULL) {
2849+ kfree(*(client->segments));
2850+ }
2851+ kfree(client->segments);
2852+ }
2853+}
2854+
2855+static void agp_add_seg_to_client(agp_client * client,
2856+ agp_segment_priv ** seg, int num_segments)
2857+{
2858+ agp_segment_priv **prev_seg;
2859+
2860+ prev_seg = client->segments;
2861+
2862+ if (prev_seg != NULL) {
2863+ agp_remove_seg_from_client(client);
2864+ }
2865+ client->num_segments = num_segments;
2866+ client->segments = seg;
2867+}
2868+
2869+/* Originally taken from linux/mm/mmap.c from the array
2870+ * protection_map.
2871+ * The original really should be exported to modules, or
2872+ * some routine which does the conversion for you
2873+ */
2874+
2875+static const pgprot_t my_protect_map[16] =
2876+{
2877+ __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
2878+ __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
2879+};
2880+
2881+static pgprot_t agp_convert_mmap_flags(int prot)
2882+{
2883+#define _trans(x,bit1,bit2) \
2884+((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
2885+
2886+ unsigned long prot_bits;
2887+ pgprot_t temp;
2888+
2889+ prot_bits = _trans(prot, PROT_READ, VM_READ) |
2890+ _trans(prot, PROT_WRITE, VM_WRITE) |
2891+ _trans(prot, PROT_EXEC, VM_EXEC);
2892+
2893+ prot_bits |= VM_SHARED;
2894+
2895+ temp = my_protect_map[prot_bits & 0x0000000f];
2896+
2897+ return temp;
2898+}
2899+
2900+static int agp_create_segment(agp_client * client, agp_region * region)
2901+{
2902+ agp_segment_priv **ret_seg;
2903+ agp_segment_priv *seg;
2904+ agp_segment *user_seg;
2905+ int i;
2906+
2907+ seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL);
2908+ if (seg == NULL) {
2909+ kfree(region->seg_list);
2910+ return -ENOMEM;
2911+ }
2912+ memset(seg, 0, (sizeof(agp_segment_priv) * region->seg_count));
2913+ user_seg = region->seg_list;
2914+
2915+ for (i = 0; i < region->seg_count; i++) {
2916+ seg[i].pg_start = user_seg[i].pg_start;
2917+ seg[i].pg_count = user_seg[i].pg_count;
2918+ seg[i].prot = agp_convert_mmap_flags(user_seg[i].prot);
2919+ }
2920+ ret_seg = kmalloc(sizeof(void *), GFP_KERNEL);
2921+ if (ret_seg == NULL) {
2922+ kfree(region->seg_list);
2923+ kfree(seg);
2924+ return -ENOMEM;
2925+ }
2926+ *ret_seg = seg;
2927+ kfree(region->seg_list);
2928+ agp_add_seg_to_client(client, ret_seg, region->seg_count);
2929+ return 0;
2930+}
2931+
2932+/* End - Routines for managing each client's segment list */
2933+
2934+/* This function must only be called when current_controller != NULL */
2935+static void agp_insert_into_pool(agp_memory * temp)
2936+{
2937+ agp_memory *prev;
2938+
2939+ prev = agp_fe.current_controller->pool;
2940+
2941+ if (prev != NULL) {
2942+ prev->prev = temp;
2943+ temp->next = prev;
2944+ }
2945+ agp_fe.current_controller->pool = temp;
2946+}
2947+
2948+
2949+/* File private list routines */
2950+
2951+agp_file_private *agp_find_private(pid_t pid)
2952+{
2953+ agp_file_private *curr;
2954+
2955+ curr = agp_fe.file_priv_list;
2956+
2957+ while (curr != NULL) {
2958+ if (curr->my_pid == pid) {
2959+ return curr;
2960+ }
2961+ curr = curr->next;
2962+ }
2963+
2964+ return NULL;
2965+}
2966+
2967+void agp_insert_file_private(agp_file_private * priv)
2968+{
2969+ agp_file_private *prev;
2970+
2971+ prev = agp_fe.file_priv_list;
2972+
2973+ if (prev != NULL) {
2974+ prev->prev = priv;
2975+ }
2976+ priv->next = prev;
2977+ agp_fe.file_priv_list = priv;
2978+}
2979+
2980+void agp_remove_file_private(agp_file_private * priv)
2981+{
2982+ agp_file_private *next;
2983+ agp_file_private *prev;
2984+
2985+ next = priv->next;
2986+ prev = priv->prev;
2987+
2988+ if (prev != NULL) {
2989+ prev->next = next;
2990+
2991+ if (next != NULL) {
2992+ next->prev = prev;
2993+ }
2994+ } else {
2995+ if (next != NULL) {
2996+ next->prev = NULL;
2997+ }
2998+ agp_fe.file_priv_list = next;
2999+ }
3000+}
3001+
3002+/* End - File flag list routines */
3003+
3004+/*
3005+ * Wrappers for agp_free_memory & agp_allocate_memory
3006+ * These make sure that internal lists are kept updated.
3007+ */
3008+static void agp_free_memory_wrap(agp_memory * memory)
3009+{
3010+ agp_remove_from_pool(memory);
3011+ agp_free_memory(memory);
3012+}
3013+
3014+static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
3015+{
3016+ agp_memory *memory;
3017+
3018+ memory = agp_allocate_memory(pg_count, type);
3019+
3020+ if (memory == NULL) {
3021+ return NULL;
3022+ }
3023+ agp_insert_into_pool(memory);
3024+ return memory;
3025+}
3026+
3027+/* Routines for managing the list of controllers -
3028+ * These routines manage the current controller, and the list of
3029+ * controllers
3030+ */
3031+
3032+static agp_controller *agp_find_controller_by_pid(pid_t id)
3033+{
3034+ agp_controller *controller;
3035+
3036+ controller = agp_fe.controllers;
3037+
3038+ while (controller != NULL) {
3039+ if (controller->pid == id) {
3040+ return controller;
3041+ }
3042+ controller = controller->next;
3043+ }
3044+
3045+ return NULL;
3046+}
3047+
3048+static agp_controller *agp_create_controller(pid_t id)
3049+{
3050+ agp_controller *controller;
3051+
3052+ controller = kmalloc(sizeof(agp_controller), GFP_KERNEL);
3053+
3054+ if (controller == NULL) {
3055+ return NULL;
3056+ }
3057+ memset(controller, 0, sizeof(agp_controller));
3058+ controller->pid = id;
3059+
3060+ return controller;
3061+}
3062+
3063+static int agp_insert_controller(agp_controller * controller)
3064+{
3065+ agp_controller *prev_controller;
3066+
3067+ prev_controller = agp_fe.controllers;
3068+ controller->next = prev_controller;
3069+
3070+ if (prev_controller != NULL) {
3071+ prev_controller->prev = controller;
3072+ }
3073+ agp_fe.controllers = controller;
3074+
3075+ return 0;
3076+}
3077+
3078+static void agp_remove_all_clients(agp_controller * controller)
3079+{
3080+ agp_client *client;
3081+ agp_client *temp;
3082+
3083+ client = controller->clients;
3084+
3085+ while (client) {
3086+ agp_file_private *priv;
3087+
3088+ temp = client;
3089+ agp_remove_seg_from_client(temp);
3090+ priv = agp_find_private(temp->pid);
3091+
3092+ if (priv != NULL) {
3093+ clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3094+ clear_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3095+ }
3096+ client = client->next;
3097+ kfree(temp);
3098+ }
3099+}
3100+
3101+static void agp_remove_all_memory(agp_controller * controller)
3102+{
3103+ agp_memory *memory;
3104+ agp_memory *temp;
3105+
3106+ memory = controller->pool;
3107+
3108+ while (memory) {
3109+ temp = memory;
3110+ memory = memory->next;
3111+ agp_free_memory_wrap(temp);
3112+ }
3113+}
3114+
3115+static int agp_remove_controller(agp_controller * controller)
3116+{
3117+ agp_controller *prev_controller;
3118+ agp_controller *next_controller;
3119+
3120+ prev_controller = controller->prev;
3121+ next_controller = controller->next;
3122+
3123+ if (prev_controller != NULL) {
3124+ prev_controller->next = next_controller;
3125+ if (next_controller != NULL) {
3126+ next_controller->prev = prev_controller;
3127+ }
3128+ } else {
3129+ if (next_controller != NULL) {
3130+ next_controller->prev = NULL;
3131+ }
3132+ agp_fe.controllers = next_controller;
3133+ }
3134+
3135+ agp_remove_all_memory(controller);
3136+ agp_remove_all_clients(controller);
3137+
3138+ if (agp_fe.current_controller == controller) {
3139+ agp_fe.current_controller = NULL;
3140+ agp_fe.backend_acquired = FALSE;
3141+ agp_backend_release();
3142+ }
3143+ kfree(controller);
3144+ return 0;
3145+}
3146+
3147+static void agp_controller_make_current(agp_controller * controller)
3148+{
3149+ agp_client *clients;
3150+
3151+ clients = controller->clients;
3152+
3153+ while (clients != NULL) {
3154+ agp_file_private *priv;
3155+
3156+ priv = agp_find_private(clients->pid);
3157+
3158+ if (priv != NULL) {
3159+ set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3160+ set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3161+ }
3162+ clients = clients->next;
3163+ }
3164+
3165+ agp_fe.current_controller = controller;
3166+}
3167+
3168+static void agp_controller_release_current(agp_controller * controller,
3169+ agp_file_private * controller_priv)
3170+{
3171+ agp_client *clients;
3172+
3173+ clear_bit(AGP_FF_IS_VALID, &(controller_priv->access_flags));
3174+ clients = controller->clients;
3175+
3176+ while (clients != NULL) {
3177+ agp_file_private *priv;
3178+
3179+ priv = agp_find_private(clients->pid);
3180+
3181+ if (priv != NULL) {
3182+ clear_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3183+ }
3184+ clients = clients->next;
3185+ }
3186+
3187+ agp_fe.current_controller = NULL;
3188+ agp_fe.used_by_controller = FALSE;
3189+ agp_backend_release();
3190+}
3191+
3192+/*
3193+ * Routines for managing client lists -
3194+ * These routines are for managing the list of auth'ed clients.
3195+ */
3196+
3197+static agp_client *agp_find_client_in_controller(agp_controller * controller,
3198+ pid_t id)
3199+{
3200+ agp_client *client;
3201+
3202+ if (controller == NULL) {
3203+ return NULL;
3204+ }
3205+ client = controller->clients;
3206+
3207+ while (client != NULL) {
3208+ if (client->pid == id) {
3209+ return client;
3210+ }
3211+ client = client->next;
3212+ }
3213+
3214+ return NULL;
3215+}
3216+
3217+static agp_controller *agp_find_controller_for_client(pid_t id)
3218+{
3219+ agp_controller *controller;
3220+
3221+ controller = agp_fe.controllers;
3222+
3223+ while (controller != NULL) {
3224+ if ((agp_find_client_in_controller(controller, id)) != NULL) {
3225+ return controller;
3226+ }
3227+ controller = controller->next;
3228+ }
3229+
3230+ return NULL;
3231+}
3232+
3233+static agp_client *agp_find_client_by_pid(pid_t id)
3234+{
3235+ agp_client *temp;
3236+
3237+ if (agp_fe.current_controller == NULL) {
3238+ return NULL;
3239+ }
3240+ temp = agp_find_client_in_controller(agp_fe.current_controller, id);
3241+ return temp;
3242+}
3243+
3244+static void agp_insert_client(agp_client * client)
3245+{
3246+ agp_client *prev_client;
3247+
3248+ prev_client = agp_fe.current_controller->clients;
3249+ client->next = prev_client;
3250+
3251+ if (prev_client != NULL) {
3252+ prev_client->prev = client;
3253+ }
3254+ agp_fe.current_controller->clients = client;
3255+ agp_fe.current_controller->num_clients++;
3256+}
3257+
3258+static agp_client *agp_create_client(pid_t id)
3259+{
3260+ agp_client *new_client;
3261+
3262+ new_client = kmalloc(sizeof(agp_client), GFP_KERNEL);
3263+
3264+ if (new_client == NULL) {
3265+ return NULL;
3266+ }
3267+ memset(new_client, 0, sizeof(agp_client));
3268+ new_client->pid = id;
3269+ agp_insert_client(new_client);
3270+ return new_client;
3271+}
3272+
3273+static int agp_remove_client(pid_t id)
3274+{
3275+ agp_client *client;
3276+ agp_client *prev_client;
3277+ agp_client *next_client;
3278+ agp_controller *controller;
3279+
3280+ controller = agp_find_controller_for_client(id);
3281+
3282+ if (controller == NULL) {
3283+ return -EINVAL;
3284+ }
3285+ client = agp_find_client_in_controller(controller, id);
3286+
3287+ if (client == NULL) {
3288+ return -EINVAL;
3289+ }
3290+ prev_client = client->prev;
3291+ next_client = client->next;
3292+
3293+ if (prev_client != NULL) {
3294+ prev_client->next = next_client;
3295+ if (next_client != NULL) {
3296+ next_client->prev = prev_client;
3297+ }
3298+ } else {
3299+ if (next_client != NULL) {
3300+ next_client->prev = NULL;
3301+ }
3302+ controller->clients = next_client;
3303+ }
3304+
3305+ controller->num_clients--;
3306+ agp_remove_seg_from_client(client);
3307+ kfree(client);
3308+ return 0;
3309+}
3310+
3311+/* End - Routines for managing client lists */
3312+
3313+/* File Operations */
3314+
3315+static int agp_mmap(struct file *file, struct vm_area_struct *vma)
3316+{
3317+ int size;
3318+ int current_size;
3319+ unsigned long offset;
3320+ agp_client *client;
3321+ agp_file_private *priv = (agp_file_private *) file->private_data;
3322+ agp_kern_info kerninfo;
3323+
3324+ AGP_LOCK();
3325+
3326+ if (agp_fe.backend_acquired != TRUE) {
3327+ AGP_UNLOCK();
3328+ return -EPERM;
3329+ }
3330+ if (!(test_bit(AGP_FF_IS_VALID, &(priv->access_flags)))) {
3331+ AGP_UNLOCK();
3332+ return -EPERM;
3333+ }
3334+ agp_copy_info(&kerninfo);
3335+ size = vma->vm_end - vma->vm_start;
3336+ current_size = kerninfo.aper_size;
3337+ current_size = current_size * 0x100000;
3338+ offset = vma->vm_offset;
3339+
3340+ if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
3341+ if ((size + offset) > current_size) {
3342+ AGP_UNLOCK();
3343+ return -EINVAL;
3344+ }
3345+ client = agp_find_client_by_pid(current->pid);
3346+
3347+ if (client == NULL) {
3348+ AGP_UNLOCK();
3349+ return -EPERM;
3350+ }
3351+ if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) {
3352+ AGP_UNLOCK();
3353+ return -EINVAL;
3354+ }
3355+ if (remap_page_range(vma->vm_start, (kerninfo.aper_base + offset),
3356+ size, vma->vm_page_prot)) {
3357+ AGP_UNLOCK();
3358+ return -EAGAIN;
3359+ }
3360+ AGP_UNLOCK();
3361+ return 0;
3362+ }
3363+ if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
3364+ if (size != current_size) {
3365+ AGP_UNLOCK();
3366+ return -EINVAL;
3367+ }
3368+ if (remap_page_range(vma->vm_start, kerninfo.aper_base,
3369+ size, vma->vm_page_prot)) {
3370+ AGP_UNLOCK();
3371+ return -EAGAIN;
3372+ }
3373+ AGP_UNLOCK();
3374+ return 0;
3375+ }
3376+ AGP_UNLOCK();
3377+ return -EPERM;
3378+}
3379+
3380+static int agp_release(struct inode *inode, struct file *file)
3381+{
3382+ agp_file_private *priv = (agp_file_private *) file->private_data;
3383+
3384+ AGP_LOCK();
3385+
3386+ if (test_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags))) {
3387+ agp_controller *controller;
3388+
3389+ controller = agp_find_controller_by_pid(priv->my_pid);
3390+
3391+ if (controller != NULL) {
3392+ if (controller == agp_fe.current_controller) {
3393+ agp_controller_release_current(controller, priv);
3394+ }
3395+ agp_remove_controller(controller);
3396+ }
3397+ }
3398+ if (test_bit(AGP_FF_IS_CLIENT, &(priv->access_flags))) {
3399+ agp_remove_client(priv->my_pid);
3400+ }
3401+ agp_remove_file_private(priv);
3402+ kfree(priv);
3403+ MOD_DEC_USE_COUNT;
3404+ AGP_UNLOCK();
3405+ return 0;
3406+}
3407+
3408+static int agp_open(struct inode *inode, struct file *file)
3409+{
3410+ int minor = MINOR(inode->i_rdev);
3411+ agp_file_private *priv;
3412+ agp_client *client;
3413+
3414+ AGP_LOCK();
3415+
3416+ if (minor != AGPGART_MINOR) {
3417+ AGP_UNLOCK();
3418+ return -ENXIO;
3419+ }
3420+ priv = kmalloc(sizeof(agp_file_private), GFP_KERNEL);
3421+
3422+ if (priv == NULL) {
3423+ AGP_UNLOCK();
3424+ return -ENOMEM;
3425+ }
3426+ memset(priv, 0, sizeof(agp_file_private));
3427+ set_bit(AGP_FF_ALLOW_CLIENT, &(priv->access_flags));
3428+ priv->my_pid = current->pid;
3429+
3430+ if ((current->uid == 0) || (current->suid == 0)) {
3431+ /* Root priv, can be controller */
3432+ set_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags));
3433+ }
3434+ client = agp_find_client_by_pid(current->pid);
3435+
3436+ if (client != NULL) {
3437+ set_bit(AGP_FF_IS_CLIENT, &(priv->access_flags));
3438+ set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3439+ }
3440+ file->private_data = (void *) priv;
3441+ agp_insert_file_private(priv);
3442+ MOD_INC_USE_COUNT;
3443+ AGP_UNLOCK();
3444+ return 0;
3445+}
3446+
3447+
3448+static long long agp_lseek(struct file *file, long long offset, int origin)
3449+{
3450+ return -ESPIPE;
3451+}
3452+
3453+static ssize_t agp_read(struct file *file, char *buf,
3454+ size_t count, loff_t * ppos)
3455+{
3456+ return -EINVAL;
3457+}
3458+
3459+static ssize_t agp_write(struct file *file, const char *buf,
3460+ size_t count, loff_t * ppos)
3461+{
3462+ return -EINVAL;
3463+}
3464+
3465+static int agpioc_info_wrap(agp_file_private * priv, unsigned long arg)
3466+{
3467+ agp_info userinfo;
3468+ agp_kern_info kerninfo;
3469+
3470+ agp_copy_info(&kerninfo);
3471+
3472+ userinfo.version.major = kerninfo.version.major;
3473+ userinfo.version.minor = kerninfo.version.minor;
3474+ userinfo.bridge_id = kerninfo.device->vendor | (kerninfo.device->device << 16);
3475+ userinfo.agp_mode = kerninfo.mode;
3476+ userinfo.aper_base = kerninfo.aper_base;
3477+ userinfo.aper_size = kerninfo.aper_size;
3478+ userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
3479+ userinfo.pg_used = kerninfo.current_memory;
3480+
3481+ if (copy_to_user((void *) arg, &userinfo, sizeof(agp_info))) {
3482+ return -EFAULT;
3483+ }
3484+ return 0;
3485+}
3486+
3487+static int agpioc_acquire_wrap(agp_file_private * priv, unsigned long arg)
3488+{
3489+ agp_controller *controller;
3490+ if (!(test_bit(AGP_FF_ALLOW_CONTROLLER, &(priv->access_flags)))) {
3491+ return -EPERM;
3492+ }
3493+ if (agp_fe.current_controller != NULL) {
3494+ return -EBUSY;
3495+ }
3496+ if ((agp_backend_acquire()) == 0) {
3497+ agp_fe.backend_acquired = TRUE;
3498+ } else {
3499+ return -EBUSY;
3500+ }
3501+
3502+ controller = agp_find_controller_by_pid(priv->my_pid);
3503+
3504+ if (controller != NULL) {
3505+ agp_controller_make_current(controller);
3506+ } else {
3507+ controller = agp_create_controller(priv->my_pid);
3508+
3509+ if (controller == NULL) {
3510+ agp_fe.backend_acquired = FALSE;
3511+ agp_backend_release();
3512+ return -ENOMEM;
3513+ }
3514+ agp_insert_controller(controller);
3515+ agp_controller_make_current(controller);
3516+ }
3517+
3518+ set_bit(AGP_FF_IS_CONTROLLER, &(priv->access_flags));
3519+ set_bit(AGP_FF_IS_VALID, &(priv->access_flags));
3520+ return 0;
3521+}
3522+
3523+static int agpioc_release_wrap(agp_file_private * priv, unsigned long arg)
3524+{
3525+ agp_controller_release_current(agp_fe.current_controller, priv);
3526+ return 0;
3527+}
3528+
3529+static int agpioc_setup_wrap(agp_file_private * priv, unsigned long arg)
3530+{
3531+ agp_setup mode;
3532+
3533+ if (copy_from_user(&mode, (void *) arg, sizeof(agp_setup))) {
3534+ return -EFAULT;
3535+ }
3536+ agp_enable(mode.agp_mode);
3537+ return 0;
3538+}
3539+
3540+static int agpioc_reserve_wrap(agp_file_private * priv, unsigned long arg)
3541+{
3542+ agp_region reserve;
3543+ agp_client *client;
3544+ agp_file_private *client_priv;
3545+
3546+
3547+ if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) {
3548+ return -EFAULT;
3549+ }
3550+ client = agp_find_client_by_pid(reserve.pid);
3551+
3552+ if (reserve.seg_count == 0) {
3553+ /* remove a client */
3554+ client_priv = agp_find_private(reserve.pid);
3555+
3556+ if (client_priv != NULL) {
3557+ set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
3558+ set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
3559+ }
3560+ if (client == NULL) {
3561+ /* client is already removed */
3562+ return 0;
3563+ }
3564+ return agp_remove_client(reserve.pid);
3565+ } else {
3566+ agp_segment *segment;
3567+
3568+ segment = kmalloc((sizeof(agp_segment) * reserve.seg_count), GFP_KERNEL);
3569+
3570+ if (segment == NULL) {
3571+ return -ENOMEM;
3572+ }
3573+ if (copy_from_user(segment, (void *) reserve.seg_list, GFP_KERNEL)) {
3574+ kfree(segment);
3575+ return -EFAULT;
3576+ }
3577+ reserve.seg_list = segment;
3578+
3579+ if (client == NULL) {
3580+ /* Create the client and add the segment */
3581+ client = agp_create_client(reserve.pid);
3582+
3583+ if (client == NULL) {
3584+ kfree(segment);
3585+ return -ENOMEM;
3586+ }
3587+ client_priv = agp_find_private(reserve.pid);
3588+
3589+ if (client_priv != NULL) {
3590+ set_bit(AGP_FF_IS_CLIENT, &(client_priv->access_flags));
3591+ set_bit(AGP_FF_IS_VALID, &(client_priv->access_flags));
3592+ }
3593+ return agp_create_segment(client, &reserve);
3594+ } else {
3595+ return agp_create_segment(client, &reserve);
3596+ }
3597+ }
3598+ /* Will never really happen */
3599+ return -EINVAL;
3600+}
3601+
3602+static int agpioc_protect_wrap(agp_file_private * priv, unsigned long arg)
3603+{
3604+ /* This function is not currently implemented */
3605+ return -EINVAL;
3606+}
3607+
3608+static int agpioc_allocate_wrap(agp_file_private * priv, unsigned long arg)
3609+{
3610+ agp_memory *memory;
3611+ agp_allocate alloc;
3612+
3613+ if (copy_from_user(&alloc, (void *) arg, sizeof(agp_allocate))) {
3614+ return -EFAULT;
3615+ }
3616+ memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type);
3617+
3618+ if (memory == NULL) {
3619+ return -ENOMEM;
3620+ }
3621+ alloc.key = memory->key;
3622+
3623+ if (copy_to_user((void *) arg, &alloc, sizeof(agp_allocate))) {
3624+ agp_free_memory_wrap(memory);
3625+ return -EFAULT;
3626+ }
3627+ return 0;
3628+}
3629+
3630+static int agpioc_deallocate_wrap(agp_file_private * priv, unsigned long arg)
3631+{
3632+ agp_memory *memory;
3633+
3634+ memory = agp_find_mem_by_key((int) arg);
3635+
3636+ if (memory == NULL) {
3637+ return -EINVAL;
3638+ }
3639+ agp_free_memory_wrap(memory);
3640+ return 0;
3641+}
3642+
3643+static int agpioc_bind_wrap(agp_file_private * priv, unsigned long arg)
3644+{
3645+ agp_bind bind_info;
3646+ agp_memory *memory;
3647+
3648+ if (copy_from_user(&bind_info, (void *) arg, sizeof(agp_bind))) {
3649+ return -EFAULT;
3650+ }
3651+ memory = agp_find_mem_by_key(bind_info.key);
3652+
3653+ if (memory == NULL) {
3654+ return -EINVAL;
3655+ }
3656+ return agp_bind_memory(memory, bind_info.pg_start);
3657+}
3658+
3659+static int agpioc_unbind_wrap(agp_file_private * priv, unsigned long arg)
3660+{
3661+ agp_memory *memory;
3662+ agp_unbind unbind;
3663+
3664+ if (copy_from_user(&unbind, (void *) arg, sizeof(agp_unbind))) {
3665+ return -EFAULT;
3666+ }
3667+ memory = agp_find_mem_by_key(unbind.key);
3668+
3669+ if (memory == NULL) {
3670+ return -EINVAL;
3671+ }
3672+ return agp_unbind_memory(memory);
3673+}
3674+
3675+static int agp_ioctl(struct inode *inode, struct file *file,
3676+ unsigned int cmd, unsigned long arg)
3677+{
3678+ agp_file_private *curr_priv = (agp_file_private *) file->private_data;
3679+ int ret_val;
3680+
3681+ AGP_LOCK();
3682+
3683+ if ((agp_fe.current_controller == NULL) &&
3684+ (cmd != AGPIOC_ACQUIRE)) {
3685+ return -EINVAL;
3686+ }
3687+ if ((agp_fe.backend_acquired != TRUE) &&
3688+ (cmd != AGPIOC_ACQUIRE)) {
3689+ return -EBUSY;
3690+ }
3691+ if (cmd != AGPIOC_ACQUIRE) {
3692+ if (!(test_bit(AGP_FF_IS_CONTROLLER, &(curr_priv->access_flags)))) {
3693+ return -EPERM;
3694+ }
3695+ /* Use the original pid of the controller, in case it's threaded */
3696+
3697+ if (agp_fe.current_controller->pid != curr_priv->my_pid) {
3698+ return -EBUSY;
3699+ }
3700+ }
3701+ switch (cmd) {
3702+ case AGPIOC_INFO:
3703+ {
3704+ ret_val = agpioc_info_wrap(curr_priv, arg);
3705+ AGP_UNLOCK();
3706+ return ret_val;
3707+ }
3708+ case AGPIOC_ACQUIRE:
3709+ {
3710+ ret_val = agpioc_acquire_wrap(curr_priv, arg);
3711+ AGP_UNLOCK();
3712+ return ret_val;
3713+ }
3714+ case AGPIOC_RELEASE:
3715+ {
3716+ ret_val = agpioc_release_wrap(curr_priv, arg);
3717+ AGP_UNLOCK();
3718+ return ret_val;
3719+ }
3720+ case AGPIOC_SETUP:
3721+ {
3722+ ret_val = agpioc_setup_wrap(curr_priv, arg);
3723+ AGP_UNLOCK();
3724+ return ret_val;
3725+ }
3726+ case AGPIOC_RESERVE:
3727+ {
3728+ ret_val = agpioc_reserve_wrap(curr_priv, arg);
3729+ AGP_UNLOCK();
3730+ return ret_val;
3731+ }
3732+ case AGPIOC_PROTECT:
3733+ {
3734+ ret_val = agpioc_protect_wrap(curr_priv, arg);
3735+ AGP_UNLOCK();
3736+ return ret_val;
3737+ }
3738+ case AGPIOC_ALLOCATE:
3739+ {
3740+ ret_val = agpioc_allocate_wrap(curr_priv, arg);
3741+ AGP_UNLOCK();
3742+ return ret_val;
3743+ }
3744+ case AGPIOC_DEALLOCATE:
3745+ {
3746+ ret_val = agpioc_deallocate_wrap(curr_priv, arg);
3747+ AGP_UNLOCK();
3748+ return ret_val;
3749+ }
3750+ case AGPIOC_BIND:
3751+ {
3752+ ret_val = agpioc_bind_wrap(curr_priv, arg);
3753+ AGP_UNLOCK();
3754+ return ret_val;
3755+ }
3756+ case AGPIOC_UNBIND:
3757+ {
3758+ ret_val = agpioc_unbind_wrap(curr_priv, arg);
3759+ AGP_UNLOCK();
3760+ return ret_val;
3761+ }
3762+ }
3763+
3764+ AGP_UNLOCK();
3765+ return -ENOTTY;
3766+}
3767+
3768+static struct file_operations agp_fops =
3769+{
3770+ agp_lseek,
3771+ agp_read,
3772+ agp_write,
3773+ NULL,
3774+ NULL,
3775+ agp_ioctl,
3776+ agp_mmap,
3777+ agp_open,
3778+ NULL,
3779+ agp_release
3780+};
3781+
3782+static struct miscdevice agp_miscdev =
3783+{
3784+ AGPGART_MINOR,
3785+ "agpgart",
3786+ &agp_fops
3787+};
3788+
3789+int agp_frontend_initialize(void)
3790+{
3791+ memset(&agp_fe, 0, sizeof(struct agp_front_data));
3792+ AGP_LOCK_INIT();
3793+
3794+ if (misc_register(&agp_miscdev)) {
3795+ printk("agpgart: unable to get minor: %d\n", AGPGART_MINOR);
3796+ return -EIO;
3797+ }
3798+ return 0;
3799+}
3800+
3801+void agp_frontend_cleanup(void)
3802+{
3803+ return;
3804+}
3805--- linux/drivers/char/Config.in.newagpdist Tue Jan 4 13:12:14 2000
3806+++ linux/drivers/char/Config.in Fri Feb 11 14:50:45 2000
3807@@ -62,7 +62,7 @@
3808 bool ' Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
3809 fi
3810 fi
3811-
3812+
3813 bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
3814 if [ "$CONFIG_MOUSE" = "y" ]; then
3815 mainmenu_option next_comment
3816@@ -116,6 +116,18 @@
3817 bool 'Tadpole ANA H8 Support' CONFIG_H8
3818 fi
3819
3820+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
3821+ dep_tristate '/dev/agpgart (AGP Support) (EXPERIMENTAL)' CONFIG_AGP m
3822+ if [ "$CONFIG_AGP" = "m" ]; then
3823+ bool ' Intel 440LX/BX/GX support' CONFIG_AGP_INTEL
3824+ bool ' Intel I810/I810 DC100/I810e support' CONFIG_AGP_I810
3825+ bool ' VIA VP3/MVP3/Apollo Pro support' CONFIG_AGP_VIA
3826+ bool ' AMD Irongate support' CONFIG_AGP_AMD
3827+ bool ' Generic SiS support' CONFIG_AGP_SIS
3828+ bool ' ALI M1541 support' CONFIG_AGP_ALI
3829+ fi
3830+fi
3831+
3832 mainmenu_option next_comment
3833 comment 'Video For Linux'
3834
3835--- linux/drivers/char/Makefile.newagpdist Fri Feb 11 14:49:48 2000
3836+++ linux/drivers/char/Makefile Fri Feb 11 14:50:45 2000
3837@@ -352,6 +352,11 @@
3838 endif
3839 endif
3840
3841+ifeq ($(CONFIG_AGP), m)
3842+ ALL_SUB_DIRS += agp
3843+ MOD_SUB_DIRS += agp
3844+endif
3845+
3846 ifeq ($(CONFIG_VIDEO_DEV),y)
3847 LX_OBJS += videodev.o
3848 else
3849--- linux/arch/i386/mm/ioremap.c.newagpdist Mon Aug 9 15:04:38 1999
3850+++ linux/arch/i386/mm/ioremap.c Fri Feb 11 14:50:45 2000
3851@@ -110,7 +110,18 @@
3852 * Don't allow anybody to remap normal RAM that we're using..
3853 */
3854 if (phys_addr < virt_to_phys(high_memory))
3855- return NULL;
3856+ {
3857+ char *temp_addr, *temp_end;
3858+ int i;
3859+
3860+ temp_addr = __va(phys_addr);
3861+ temp_end = temp_addr + (size - 1);
3862+
3863+ for(i = MAP_NR(temp_addr); i < MAP_NR(temp_end); i++) {
3864+ if(!PageReserved(mem_map + i))
3865+ return NULL;
3866+ }
3867+ }
3868
3869 /*
3870 * Mappings have to be page-aligned
3871--- linux/Documentation/Configure.help.newagpdist Fri Feb 11 14:49:49 2000
3872+++ linux/Documentation/Configure.help Fri Feb 11 14:50:45 2000
3873@@ -9430,6 +9430,20 @@
3874 sampling), then say Y here, and read Documentation/rtc.txt for
3875 details.
3876
3877+AGP/GART support
3878+CONFIG_AGP
3879+ This provides a kernel interface (/dev/agpgart) for programming AGP
3880+ transfers on motherboards that support them. Primarily, this is used
3881+ for hardware-accelerated 3d graphics, though any other AGP device
3882+ could take advantage of it.
3883+
3884+ If you have a 3d-capable AGP video card say 'M' or 'Y' here.
3885+ Otherwise, say 'N'.
3886+
3887+ You will also have to indicate support for your specific chipset.
3888+ Consult the output of lspci, your motherboard manual, or the inside
3889+ of your computer if unsure what to choose. Multiple selections are ok.
3890+
3891 Tadpole ANA H8 Support
3892 CONFIG_H8
3893 The Hitachi H8/337 is a microcontroller used to deal with the power
This page took 0.453477 seconds and 4 git commands to generate.