]> git.pld-linux.org Git - packages/kernel.git/blob - linux-newagpdist.patch
- added description of djurban's branch
[packages/kernel.git] / linux-newagpdist.patch
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.500707 seconds and 3 git commands to generate.