diff options
Diffstat (limited to 'drivers/char/agp/frontend.c')
| -rw-r--r-- | drivers/char/agp/frontend.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 0f2ed2aa2d8..b29703324e9 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -31,19 +31,20 @@ #include <linux/module.h> #include <linux/mman.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/miscdevice.h> #include <linux/agp_backend.h> #include <linux/agpgart.h> #include <linux/slab.h> #include <linux/mm.h> +#include <linux/fs.h> +#include <linux/sched.h> #include <asm/uaccess.h> #include <asm/pgtable.h> #include "agp.h" -static struct agp_front_data agp_fe; +struct agp_front_data agp_fe; -static struct agp_memory *agp_find_mem_by_key(int key) +struct agp_memory *agp_find_mem_by_key(int key) { struct agp_memory *curr; @@ -159,7 +160,7 @@ static pgprot_t agp_convert_mmap_flags(int prot) return vm_get_page_prot(prot_bits); } -static int agp_create_segment(struct agp_client *client, struct agp_region *region) +int agp_create_segment(struct agp_client *client, struct agp_region *region) { struct agp_segment_priv **ret_seg; struct agp_segment_priv *seg; @@ -211,7 +212,7 @@ static void agp_insert_into_pool(struct agp_memory * temp) /* File private list routines */ -static struct agp_file_private *agp_find_private(pid_t pid) +struct agp_file_private *agp_find_private(pid_t pid) { struct agp_file_private *curr; @@ -266,13 +267,13 @@ static void agp_remove_file_private(struct agp_file_private * priv) * Wrappers for agp_free_memory & agp_allocate_memory * These make sure that internal lists are kept updated. */ -static void agp_free_memory_wrap(struct agp_memory *memory) +void agp_free_memory_wrap(struct agp_memory *memory) { agp_remove_from_pool(memory); agp_free_memory(memory); } -static struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type) +struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type) { struct agp_memory *memory; @@ -393,7 +394,7 @@ static int agp_remove_controller(struct agp_controller *controller) if (agp_fe.current_controller == controller) { agp_fe.current_controller = NULL; - agp_fe.backend_acquired = FALSE; + agp_fe.backend_acquired = false; agp_backend_release(agp_bridge); } kfree(controller); @@ -441,7 +442,7 @@ static void agp_controller_release_current(struct agp_controller *controller, } agp_fe.current_controller = NULL; - agp_fe.used_by_controller = FALSE; + agp_fe.used_by_controller = false; agp_backend_release(agp_bridge); } @@ -484,7 +485,7 @@ static struct agp_controller *agp_find_controller_for_client(pid_t id) return NULL; } -static struct agp_client *agp_find_client_by_pid(pid_t id) +struct agp_client *agp_find_client_by_pid(pid_t id) { struct agp_client *temp; @@ -509,7 +510,7 @@ static void agp_insert_client(struct agp_client *client) agp_fe.current_controller->num_clients++; } -static struct agp_client *agp_create_client(pid_t id) +struct agp_client *agp_create_client(pid_t id) { struct agp_client *new_client; @@ -522,7 +523,7 @@ static struct agp_client *agp_create_client(pid_t id) return new_client; } -static int agp_remove_client(pid_t id) +int agp_remove_client(pid_t id) { struct agp_client *client; struct agp_client *prev_client; @@ -571,7 +572,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) mutex_lock(&(agp_fe.agp_mutex)); - if (agp_fe.backend_acquired != TRUE) + if (agp_fe.backend_acquired != true) goto out_eperm; if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) @@ -601,7 +602,8 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = kerninfo.vm_ops; } else if (io_remap_pfn_range(vma, vma->vm_start, (kerninfo.aper_base + offset) >> PAGE_SHIFT, - size, vma->vm_page_prot)) { + size, + pgprot_writecombine(vma->vm_page_prot))) { goto out_again; } mutex_unlock(&(agp_fe.agp_mutex)); @@ -616,8 +618,9 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma) if (kerninfo.vm_ops) { vma->vm_ops = kerninfo.vm_ops; } else if (io_remap_pfn_range(vma, vma->vm_start, - kerninfo.aper_base >> PAGE_SHIFT, - size, vma->vm_page_prot)) { + kerninfo.aper_base >> PAGE_SHIFT, + size, + pgprot_writecombine(vma->vm_page_prot))) { goto out_again; } mutex_unlock(&(agp_fe.agp_mutex)); @@ -673,24 +676,25 @@ static int agp_open(struct inode *inode, struct file *file) int minor = iminor(inode); struct agp_file_private *priv; struct agp_client *client; - int rc = -ENXIO; - - mutex_lock(&(agp_fe.agp_mutex)); if (minor != AGPGART_MINOR) - goto err_out; + return -ENXIO; + + mutex_lock(&(agp_fe.agp_mutex)); priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL); - if (priv == NULL) - goto err_out_nomem; + if (priv == NULL) { + mutex_unlock(&(agp_fe.agp_mutex)); + return -ENOMEM; + } set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); priv->my_pid = current->pid; - if ((current->uid == 0) || (current->suid == 0)) { + if (capable(CAP_SYS_RAWIO)) /* Root priv, can be controller */ set_bit(AGP_FF_ALLOW_CONTROLLER, &priv->access_flags); - } + client = agp_find_client_by_pid(current->pid); if (client != NULL) { @@ -700,14 +704,10 @@ static int agp_open(struct inode *inode, struct file *file) file->private_data = (void *) priv; agp_insert_file_private(priv); DBG("private=%p, client=%p", priv, client); - mutex_unlock(&(agp_fe.agp_mutex)); - return 0; -err_out_nomem: - rc = -ENOMEM; -err_out: mutex_unlock(&(agp_fe.agp_mutex)); - return rc; + + return 0; } @@ -730,6 +730,7 @@ static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg) agp_copy_info(agp_bridge, &kerninfo); + memset(&userinfo, 0, sizeof(userinfo)); userinfo.version.major = kerninfo.version.major; userinfo.version.minor = kerninfo.version.minor; userinfo.bridge_id = kerninfo.device->vendor | @@ -746,7 +747,7 @@ static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg) return 0; } -static int agpioc_acquire_wrap(struct agp_file_private *priv) +int agpioc_acquire_wrap(struct agp_file_private *priv) { struct agp_controller *controller; @@ -766,7 +767,7 @@ static int agpioc_acquire_wrap(struct agp_file_private *priv) atomic_inc(&agp_bridge->agp_in_use); - agp_fe.backend_acquired = TRUE; + agp_fe.backend_acquired = true; controller = agp_find_controller_by_pid(priv->my_pid); @@ -776,7 +777,7 @@ static int agpioc_acquire_wrap(struct agp_file_private *priv) controller = agp_create_controller(priv->my_pid); if (controller == NULL) { - agp_fe.backend_acquired = FALSE; + agp_fe.backend_acquired = false; agp_backend_release(agp_bridge); return -ENOMEM; } @@ -789,14 +790,14 @@ static int agpioc_acquire_wrap(struct agp_file_private *priv) return 0; } -static int agpioc_release_wrap(struct agp_file_private *priv) +int agpioc_release_wrap(struct agp_file_private *priv) { DBG(""); agp_controller_release_current(agp_fe.current_controller, priv); return 0; } -static int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg) +int agpioc_setup_wrap(struct agp_file_private *priv, void __user *arg) { struct agp_setup mode; @@ -876,7 +877,7 @@ static int agpioc_reserve_wrap(struct agp_file_private *priv, void __user *arg) return -EINVAL; } -static int agpioc_protect_wrap(struct agp_file_private *priv) +int agpioc_protect_wrap(struct agp_file_private *priv) { DBG(""); /* This function is not currently implemented */ @@ -892,6 +893,9 @@ static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg) if (copy_from_user(&alloc, arg, sizeof(struct agp_allocate))) return -EFAULT; + if (alloc.type >= AGP_USER_TYPES) + return -EINVAL; + memory = agp_allocate_memory_wrap(alloc.pg_count, alloc.type); if (memory == NULL) @@ -907,7 +911,7 @@ static int agpioc_allocate_wrap(struct agp_file_private *priv, void __user *arg) return 0; } -static int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg) +int agpioc_deallocate_wrap(struct agp_file_private *priv, int arg) { struct agp_memory *memory; @@ -955,7 +959,7 @@ static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg) return agp_unbind_memory(memory); } -static int agp_ioctl(struct inode *inode, struct file *file, +static long agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct agp_file_private *curr_priv = file->private_data; @@ -969,7 +973,7 @@ static int agp_ioctl(struct inode *inode, struct file *file, ret_val = -EINVAL; goto ioctl_out; } - if ((agp_fe.backend_acquired != TRUE) && + if ((agp_fe.backend_acquired != true) && (cmd != AGPIOC_ACQUIRE)) { ret_val = -EBUSY; goto ioctl_out; @@ -1028,6 +1032,9 @@ static int agp_ioctl(struct inode *inode, struct file *file, case AGPIOC_UNBIND: ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg); break; + + case AGPIOC_CHIPSET_FLUSH: + break; } ioctl_out: @@ -1042,7 +1049,10 @@ static const struct file_operations agp_fops = .llseek = no_llseek, .read = agp_read, .write = agp_write, - .ioctl = agp_ioctl, + .unlocked_ioctl = agp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_agp_ioctl, +#endif .mmap = agp_mmap, .open = agp_open, .release = agp_release, |
