[MPlayer-matrox] r272 - mga_vid/trunk/mga_vid.c
attila
subversion at mplayerhq.hu
Sun Oct 19 17:59:42 CEST 2008
Author: attila
Date: Sun Oct 19 17:59:42 2008
New Revision: 272
Log:
* change ioctl to new interface, that doesn't use BKL
* add compat_ioctl
* add spinlocks to all accesses of mga_card_t
Modified:
mga_vid/trunk/mga_vid.c
Modified: mga_vid/trunk/mga_vid.c
==============================================================================
--- mga_vid/trunk/mga_vid.c (original)
+++ mga_vid/trunk/mga_vid.c Sun Oct 19 17:59:42 2008
@@ -61,6 +61,8 @@
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/spinlock.h>
+
#include "mga_vid.h"
#ifdef CONFIG_MTRR
@@ -286,6 +288,8 @@ typedef struct mga_card_s {
unsigned char colkey_mask[4];
int next_frame;
+
+ spinlock_t lock;
} mga_card_t;
static unsigned int mga_cards_num = 0;
@@ -653,26 +657,29 @@ static int mga_vid_set_config(mga_card_t
return 0;
}
-static int mga_vid_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+static long mga_vid_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- int frame, result;
+ int frame, result = 0;
uint32_t tmp;
mga_card_t *card = (mga_card_t *) file->private_data;
+ spin_lock(&card->lock);
+
switch (cmd) {
case MGA_VID_GET_VERSION:
tmp = MGA_VID_VERSION;
if (copy_to_user((uint32_t *) arg, &tmp, sizeof(uint32_t))) {
printk(KERN_ERR "mga_vid: failed copy %p to userspace %p\n", &tmp, (uint32_t *) arg);
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
break;
case MGA_VID_CONFIG:
if (copy_from_user (&card->config, (mga_vid_config_t *) arg, sizeof(mga_vid_config_t))) {
printk(KERN_ERR "mga_vid: failed copy from userspace\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
// return some information back to user space in case we hit an error
card->config.card_type = card->card_type;
@@ -680,35 +687,41 @@ static int mga_vid_ioctl(struct inode *i
card->config.capabilities = 0;
if (copy_to_user ((mga_vid_config_t *) arg, &card->config, sizeof(mga_vid_config_t))) {
printk(KERN_ERR "mga_vid: failed copy to userspace\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
if (card->config.version != MGA_VID_VERSION) {
printk(KERN_ERR "mga_vid: incompatible version! driver: %X requested: %X\n", MGA_VID_VERSION, card->config.version);
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
if (card->config.frame_size == 0 || card->config.frame_size > 1920 * 1080 * 2) {
printk(KERN_ERR "mga_vid: illegal frame_size: %d\n", card->config.frame_size);
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
if (card->config.num_frames < 1 || card->config.num_frames > 4) {
printk(KERN_ERR "mga_vid: illegal num_frames: %d\n", card->config.num_frames);
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
if ((card->config.src_width > 1024 || card->config.src_height > 1024)
&& (card->card_type != MGA_G550 && card->config.src_height > 1024)) {
printk(KERN_ERR "mga_vid: overlay sizes bigger than 1024x1024 are not supported with this card type, rescale the picture in software\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
card->src_base = (card->ram_size * 0x100000 - card->config.num_frames * card->config.frame_size - card->top_reserved);
if (card->src_base < 0) {
printk(KERN_ERR "mga_vid: not enough memory for frames!\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
card->src_base &= (~0xFFFF); // 64k boundary
#ifdef MP_DEBUG
@@ -716,13 +729,14 @@ static int mga_vid_ioctl(struct inode *i
#endif
if (copy_to_user ((mga_vid_config_t *) arg, &card->config, sizeof(mga_vid_config_t))) {
printk(KERN_ERR "mga_vid: failed copy to userspace\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
result = mga_vid_set_config(card);
if (!result)
card->configured = 1;
- return result;
+ goto ioctl_out;
break;
case MGA_VID_ON:
@@ -750,7 +764,8 @@ static int mga_vid_ioctl(struct inode *i
case MGA_VID_FSEL:
if (copy_from_user(&frame, (int *)arg, sizeof(uint32_t))) {
printk(KERN_ERR "mga_vid: FSEL failed copy from userspace\n");
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
mga_vid_frame_sel(card, frame);
@@ -763,7 +778,8 @@ static int mga_vid_ioctl(struct inode *i
if (copy_to_user((uint32_t *) arg, &tmp, sizeof(uint32_t))) {
printk(KERN_ERR "mga_vid: failed copy %p to userspace %p\n", &tmp, (uint32_t *) arg);
- return (-EFAULT);
+ result = -EFAULT;
+ goto ioctl_out;
}
break;
@@ -778,10 +794,13 @@ static int mga_vid_ioctl(struct inode *i
default:
printk(KERN_ERR "mga_vid: Invalid ioctl\n");
- return (-EINVAL);
+ result = -EINVAL;
+ goto ioctl_out;
}
- return 0;
+ ioctl_out:
+ spin_unlock(&card->lock);
+ return result;
}
static void cards_init(mga_card_t * card, struct pci_dev *dev, int card_number, int card_type);
@@ -949,6 +968,7 @@ static ssize_t mga_vid_write(struct file
static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma)
{
mga_card_t *card = (mga_card_t *) file->private_data;
+ spin_lock(&card->lock);
#ifdef MP_DEBUG
printk(KERN_DEBUG "mga_vid: mapping video memory into userspace\n");
@@ -956,6 +976,7 @@ static int mga_vid_mmap(struct file *fil
if (!card->configured) {
printk(KERN_ERR "mga_vid: card is not configured, cannot mmap\n");
+ spin_unlock(&card->lock);
return (-EAGAIN);
}
//FIXME: should we set VM_IO too ? remap_pfn_range does it for us,
@@ -966,9 +987,11 @@ static int mga_vid_mmap(struct file *fil
(card->mem_base + card->src_base) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
printk(KERN_ERR "mga_vid: error mapping video memory\n");
+ spin_unlock(&card->lock);
return (-EAGAIN);
}
+ spin_unlock(&card->lock);
return 0;
}
@@ -982,6 +1005,7 @@ static int mga_vid_release(struct inode
#endif
card = (mga_card_t *) file->private_data;
+ spin_lock(&card->lock);
card->vid_src_ready = 0;
card->regs.besctl &= ~1;
@@ -989,6 +1013,7 @@ static int mga_vid_release(struct inode
// card->config.colkey_on=0; //!!!
mga_vid_write_regs(card, 1);
card->vid_in_use = 0;
+ spin_unlock(&card->lock);
return 0;
}
@@ -1011,11 +1036,16 @@ static int mga_vid_open(struct inode *in
card = (mga_card_t *) file->private_data;
+ spin_lock(&card->lock);
if (card->vid_in_use == 1)
+ {
+ spin_unlock(&card->lock);
return (-EBUSY);
+ }
card->vid_in_use = 1;
card->configured = 0;
+ spin_unlock(&card->lock);
return 0;
}
@@ -1023,7 +1053,8 @@ static struct file_operations mga_vid_fo
llseek:mga_vid_lseek,
read:mga_vid_read,
write:mga_vid_write,
- ioctl:mga_vid_ioctl,
+ unlocked_ioctl:mga_vid_ioctl,
+ compat_ioctl:mga_vid_ioctl,
mmap:mga_vid_mmap,
open:mga_vid_open,
release:mga_vid_release
@@ -1033,6 +1064,7 @@ static void cards_init(mga_card_t * card
{
unsigned int card_option;
+ spin_lock_init(&card->lock);
card->pci_dev = dev;
card->card_type = card_type;
More information about the MPlayer-matrox
mailing list