29 #include <linux/types.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/mman.h>
33 #include <linux/pci.h>
37 #include <linux/agpgart.h>
38 #include <linux/slab.h>
41 #include <linux/sched.h>
42 #include <asm/uaccess.h>
43 #include <asm/pgtable.h>
55 curr =
agp_fe.current_controller->pool;
57 while (curr !=
NULL) {
63 DBG(
"key=%d -> mem=%p", key, curr);
110 pg_start = offset / 4096;
111 pg_count = size / 4096;
116 if ((seg[i].pg_start == pg_start) &&
126 static void agp_remove_seg_from_client(
struct agp_client *client)
128 DBG(
"client=%p", client);
132 DBG(
"Freeing %p from client %p", *(client->
segments), client);
135 DBG(
"Freeing %p from client %p", client->
segments, client);
141 static void agp_add_seg_to_client(
struct agp_client *client,
148 if (prev_seg !=
NULL)
149 agp_remove_seg_from_client(client);
151 DBG(
"Adding seg %p (%d segments) to client %p", seg, num_segments, client);
158 unsigned long prot_bits;
160 prot_bits = calc_vm_prot_bits(prot) | VM_SHARED;
179 for (i = 0; i < region->
seg_count; i++) {
182 seg[
i].
prot = agp_convert_mmap_flags(user_seg[i].
prot);
188 if (ret_seg ==
NULL) {
193 agp_add_seg_to_client(client, ret_seg, region->
seg_count);
200 static void agp_insert_into_pool(
struct agp_memory * temp)
204 prev =
agp_fe.current_controller->pool;
220 curr =
agp_fe.file_priv_list;
222 while (curr !=
NULL) {
235 prev =
agp_fe.file_priv_list;
273 agp_remove_from_pool(memory);
285 agp_insert_into_pool(memory);
298 controller =
agp_fe.controllers;
300 while (controller !=
NULL) {
301 if (controller->
pid ==
id)
303 controller = controller->
next;
314 if (controller ==
NULL)
317 controller->
pid =
id;
321 static int agp_insert_controller(
struct agp_controller *controller)
325 prev_controller =
agp_fe.controllers;
326 controller->
next = prev_controller;
328 if (prev_controller !=
NULL)
336 static void agp_remove_all_clients(
struct agp_controller *controller)
347 agp_remove_seg_from_client(temp);
354 client = client->
next;
359 static void agp_remove_all_memory(
struct agp_controller *controller)
364 memory = controller->
pool;
368 memory = memory->
next;
373 static int agp_remove_controller(
struct agp_controller *controller)
378 prev_controller = controller->
prev;
379 next_controller = controller->
next;
381 if (prev_controller !=
NULL) {
382 prev_controller->
next = next_controller;
383 if (next_controller !=
NULL)
384 next_controller->
prev = prev_controller;
387 if (next_controller !=
NULL)
390 agp_fe.controllers = next_controller;
393 agp_remove_all_memory(controller);
394 agp_remove_all_clients(controller);
396 if (
agp_fe.current_controller == controller) {
398 agp_fe.backend_acquired =
false;
405 static void agp_controller_make_current(
struct agp_controller *controller)
411 while (clients !=
NULL) {
420 clients = clients->
next;
426 static void agp_controller_release_current(
struct agp_controller *controller,
434 while (clients !=
NULL) {
442 clients = clients->
next;
446 agp_fe.used_by_controller =
false;
460 if (controller ==
NULL)
465 while (client !=
NULL) {
466 if (client->
pid ==
id)
468 client = client->
next;
478 controller =
agp_fe.controllers;
480 while (controller !=
NULL) {
481 if ((agp_find_client_in_controller(controller,
id)) !=
NULL)
483 controller = controller->
next;
496 temp = agp_find_client_in_controller(
agp_fe.current_controller,
id);
500 static void agp_insert_client(
struct agp_client *client)
504 prev_client =
agp_fe.current_controller->clients;
505 client->
next = prev_client;
507 if (prev_client !=
NULL)
511 agp_fe.current_controller->num_clients++;
519 if (new_client ==
NULL)
522 new_client->
pid =
id;
523 agp_insert_client(new_client);
534 controller = agp_find_controller_for_client(
id);
535 if (controller ==
NULL)
538 client = agp_find_client_in_controller(controller,
id);
542 prev_client = client->
prev;
543 next_client = client->
next;
545 if (prev_client !=
NULL) {
546 prev_client->
next = next_client;
547 if (next_client !=
NULL)
548 next_client->
prev = prev_client;
551 if (next_client !=
NULL)
553 controller->
clients = next_client;
557 agp_remove_seg_from_client(client);
568 unsigned int size, current_size;
576 if (
agp_fe.backend_acquired !=
true)
584 current_size = kerninfo.aper_size;
585 current_size = current_size * 0x100000;
587 DBG(
"%lx:%lx", offset, offset+size);
590 if ((size + offset) > current_size)
598 if (!agp_find_seg_in_client(client, offset, size, vma->
vm_page_prot))
601 DBG(
"client vm_ops=%p", kerninfo.vm_ops);
602 if (kerninfo.vm_ops) {
603 vma->
vm_ops = kerninfo.vm_ops;
614 if (size != current_size)
617 DBG(
"controller vm_ops=%p", kerninfo.vm_ops);
618 if (kerninfo.vm_ops) {
619 vma->
vm_ops = kerninfo.vm_ops;
642 static int agp_release(
struct inode *
inode,
struct file *file)
648 DBG(
"priv=%p", priv);
653 controller = agp_find_controller_by_pid(priv->
my_pid);
655 if (controller !=
NULL) {
656 if (controller ==
agp_fe.current_controller)
657 agp_controller_release_current(controller, priv);
658 agp_remove_controller(controller);
666 agp_remove_file_private(priv);
673 static int agp_open(
struct inode *inode,
struct file *file)
675 int minor = iminor(inode);
699 if (client !=
NULL) {
704 agp_insert_file_private(priv);
705 DBG(
"private=%p, client=%p", priv, client);
713 static ssize_t agp_read(
struct file *file,
char __user *
buf,
714 size_t count, loff_t * ppos)
719 static ssize_t agp_write(
struct file *file,
const char __user *
buf,
720 size_t count, loff_t * ppos)
732 userinfo.version.major = kerninfo.version.major;
733 userinfo.version.minor = kerninfo.version.minor;
734 userinfo.bridge_id = kerninfo.device->vendor |
735 (kerninfo.device->device << 16);
736 userinfo.agp_mode = kerninfo.mode;
737 userinfo.aper_base = kerninfo.aper_base;
738 userinfo.aper_size = kerninfo.aper_size;
739 userinfo.pg_total = userinfo.pg_system = kerninfo.max_memory;
740 userinfo.pg_used = kerninfo.current_memory;
768 agp_fe.backend_acquired =
true;
770 controller = agp_find_controller_by_pid(priv->
my_pid);
772 if (controller !=
NULL) {
773 agp_controller_make_current(controller);
775 controller = agp_create_controller(priv->
my_pid);
777 if (controller ==
NULL) {
778 agp_fe.backend_acquired =
false;
782 agp_insert_controller(controller);
783 agp_controller_make_current(controller);
794 agp_controller_release_current(
agp_fe.current_controller, priv);
810 static int agpioc_reserve_wrap(
struct agp_file_private *priv,
void __user *arg)
829 if (client_priv !=
NULL) {
833 if (client ==
NULL) {
841 if (
reserve.seg_count >= 16384)
857 if (client ==
NULL) {
861 if (client ==
NULL) {
867 if (client_priv !=
NULL) {
885 static int agpioc_allocate_wrap(
struct agp_file_private *priv,
void __user *arg)
902 alloc.key = memory->
key;
926 static int agpioc_bind_wrap(
struct agp_file_private *priv,
void __user *arg)
943 static int agpioc_unbind_wrap(
struct agp_file_private *priv,
void __user *arg)
960 static long agp_ioctl(
struct file *file,
961 unsigned int cmd,
unsigned long arg)
966 DBG(
"priv=%p, cmd=%x", curr_priv, cmd);
974 if ((
agp_fe.backend_acquired !=
true) &&
987 if (
agp_fe.current_controller->pid != curr_priv->
my_pid) {
995 ret_val = agpioc_info_wrap(curr_priv, (
void __user *) arg);
1011 ret_val = agpioc_reserve_wrap(curr_priv, (
void __user *) arg);
1019 ret_val = agpioc_allocate_wrap(curr_priv, (
void __user *) arg);
1027 ret_val = agpioc_bind_wrap(curr_priv, (
void __user *) arg);
1031 ret_val = agpioc_unbind_wrap(curr_priv, (
void __user *) arg);
1039 DBG(
"ioctl returns %d\n", ret_val);
1050 .unlocked_ioctl = agp_ioctl,
1051 #ifdef CONFIG_COMPAT
1056 .release = agp_release,