[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