aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/agp/frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp/frontend.c')
-rw-r--r--drivers/char/agp/frontend.c145
1 files changed, 66 insertions, 79 deletions
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 17f520c9d47..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;
@@ -151,38 +152,15 @@ static void agp_add_seg_to_client(struct agp_client *client,
client->segments = seg;
}
-/* Originally taken from linux/mm/mmap.c from the array
- * protection_map.
- * The original really should be exported to modules, or
- * some routine which does the conversion for you
- */
-
-static const pgprot_t my_protect_map[16] =
-{
- __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
- __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
-};
-
static pgprot_t agp_convert_mmap_flags(int prot)
{
-#define _trans(x,bit1,bit2) \
-((bit1==bit2)?(x&bit1):(x&bit1)?bit2:0)
-
unsigned long prot_bits;
- pgprot_t temp;
- prot_bits = _trans(prot, PROT_READ, VM_READ) |
- _trans(prot, PROT_WRITE, VM_WRITE) |
- _trans(prot, PROT_EXEC, VM_EXEC);
-
- prot_bits |= VM_SHARED;
-
- temp = my_protect_map[prot_bits & 0x0000000f];
-
- return temp;
+ prot_bits = calc_vm_prot_bits(prot) | VM_SHARED;
+ 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;
@@ -234,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;
@@ -289,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;
@@ -416,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);
@@ -464,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);
}
@@ -507,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;
@@ -532,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;
@@ -545,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;
@@ -592,9 +570,9 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
struct agp_file_private *priv = file->private_data;
struct agp_kern_info kerninfo;
- down(&(agp_fe.agp_mutex));
+ 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)))
@@ -624,10 +602,11 @@ 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;
}
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return 0;
}
@@ -639,24 +618,25 @@ 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;
}
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return 0;
}
out_eperm:
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return -EPERM;
out_inval:
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return -EINVAL;
out_again:
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return -EAGAIN;
}
@@ -664,7 +644,7 @@ static int agp_release(struct inode *inode, struct file *file)
{
struct agp_file_private *priv = file->private_data;
- down(&(agp_fe.agp_mutex));
+ mutex_lock(&(agp_fe.agp_mutex));
DBG("priv=%p", priv);
@@ -687,7 +667,7 @@ static int agp_release(struct inode *inode, struct file *file)
agp_remove_file_private(priv);
kfree(priv);
file->private_data = NULL;
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return 0;
}
@@ -696,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;
-
- down(&(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) {
@@ -723,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);
- up(&(agp_fe.agp_mutex));
- return 0;
-err_out_nomem:
- rc = -ENOMEM;
-err_out:
- up(&(agp_fe.agp_mutex));
- return rc;
+ mutex_unlock(&(agp_fe.agp_mutex));
+
+ return 0;
}
@@ -753,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 |
@@ -769,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;
@@ -781,7 +759,7 @@ static int agpioc_acquire_wrap(struct agp_file_private *priv)
if (agp_fe.current_controller != NULL)
return -EBUSY;
- if(!agp_bridge)
+ if (!agp_bridge)
return -ENODEV;
if (atomic_read(&agp_bridge->agp_in_use))
@@ -789,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);
@@ -799,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;
}
@@ -812,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;
@@ -899,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 */
@@ -915,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)
@@ -930,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;
@@ -978,21 +959,21 @@ 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;
int ret_val = -ENOTTY;
DBG("priv=%p, cmd=%x", curr_priv, cmd);
- down(&(agp_fe.agp_mutex));
+ mutex_lock(&(agp_fe.agp_mutex));
if ((agp_fe.current_controller == NULL) &&
(cmd != AGPIOC_ACQUIRE)) {
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;
@@ -1051,21 +1032,27 @@ 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:
DBG("ioctl returns %d\n", ret_val);
- up(&(agp_fe.agp_mutex));
+ mutex_unlock(&(agp_fe.agp_mutex));
return ret_val;
}
-static struct file_operations agp_fops =
+static const struct file_operations agp_fops =
{
.owner = THIS_MODULE,
.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,
@@ -1081,7 +1068,7 @@ static struct miscdevice agp_miscdev =
int agp_frontend_initialize(void)
{
memset(&agp_fe, 0, sizeof(struct agp_front_data));
- sema_init(&(agp_fe.agp_mutex), 1);
+ mutex_init(&(agp_fe.agp_mutex));
if (misc_register(&agp_miscdev)) {
printk(KERN_ERR PFX "unable to get minor: %d\n", AGPGART_MINOR);