diff driver/pt1_pci.c @ 31:289794dc265f

adapted to use of multiple number of pt1: - now pt1_open() checks major number. - passes unique device name to device_create(). - handles device[] bit carefully.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 03 Mar 2009 05:15:40 +0900
parents eb694d8e4c7e
children 65c8ac567074
line wrap: on
line diff
--- a/driver/pt1_pci.c	Sun Mar 01 23:32:38 2009 +0900
+++ b/driver/pt1_pci.c	Tue Mar 03 05:15:40 2009 +0900
@@ -51,7 +51,7 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+static int debug = 7;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 static int lnb = 0;			/* LNB OFF:0 +11V:1 +15V:2 */
 
 module_param(debug, int, 0);
@@ -97,6 +97,7 @@
 	void			*dmaptr[DMA_RING_SIZE] ;
 	struct	task_struct	*kthread;
 	dev_t			dev ;
+	int			card_number;
 	__u32			base_minor ;
 	struct	cdev	cdev[MAX_CHANNEL];
 	wait_queue_head_t	dma_wait_q ;// for poll on reading
@@ -284,6 +285,7 @@
 static int pt1_open(struct inode *inode, struct file *file)
 {
 
+	int		major = imajor(inode);
 	int		minor = iminor(inode);
 	int		lp ;
 	int		lp2 ;
@@ -293,8 +295,11 @@
 		if(device[lp] == NULL){
 			return -EIO ;
 		}
-		if((device[lp]->base_minor <= minor) &&
-			((device[lp]->base_minor + MAX_CHANNEL) > minor)){
+
+		if(MAJOR(device[lp]->dev) == major &&
+		   device[lp]->base_minor <= minor &&
+		   device[lp]->base_minor + MAX_CHANNEL > minor) {
+
 			mutex_lock(&device[lp]->lock);
 			for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){
 				channel = device[lp]->channel[lp2] ;
@@ -329,7 +334,7 @@
 	mutex_lock(&channel->ptr->lock);
 	SetStream(channel->ptr->regs, channel->channel, FALSE);
 	channel->valid = FALSE ;
-	printk(KERN_INFO "(%d)Drop=%08d:%08d:%08d:%08d\n", iminor(inode), channel->drop,
+	printk(KERN_INFO "(%d:%d)Drop=%08d:%08d:%08d:%08d\n", imajor(inode), iminor(inode), channel->drop,
 						channel->overflow, channel->counetererr, channel->transerr);
 	channel->overflow = 0 ;
 	channel->counetererr = 0 ;
@@ -653,15 +658,18 @@
 	minor = MINOR(dev_conf->dev) ;
 	dev_conf->base_minor = minor ;
 	for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
+		printk(KERN_INFO "PT1: device[%d]=%p\n", lp, device[lp]);
 		if(device[lp] == NULL){
 			device[lp] = dev_conf ;
+			dev_conf->card_number = lp;
 			break ;
 		}
 	}
 	for(lp = 0 ; lp < MAX_CHANNEL ; lp++){
 		cdev_init(&dev_conf->cdev[lp], &pt1_fops);
 		dev_conf->cdev[lp].owner = THIS_MODULE;
-		cdev_add(&dev_conf->cdev[lp], MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1);
+		cdev_add(&dev_conf->cdev[lp],
+			 MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)), 1);
 		channel = kzalloc(sizeof(PT1_CHANNEL), GFP_KERNEL);
 		if(!channel){
 			printk(KERN_ERR "PT1:out of memory !");
@@ -699,13 +707,24 @@
 			goto out_err_v4l;
 		}
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-		device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
-						(MINOR(dev_conf->dev) + lp)), NULL,
-						"pt1video%u", MINOR(dev_conf->dev) + lp);
+		printk(KERN_INFO "PT1: card_number = %d\n",
+		       dev_conf->card_number);
+		device_create(pt1video_class,
+			      NULL,
+			      MKDEV(MAJOR(dev_conf->dev),
+				    (MINOR(dev_conf->dev) + lp)),
+			      NULL,
+			      "pt1video%u",
+			      MINOR(dev_conf->dev) + lp +
+			      dev_conf->card_number * MAX_CHANNEL);
 #else
-		device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
-						(MINOR(dev_conf->dev) + lp)),
-						"pt1video%u", MINOR(dev_conf->dev) + lp);
+		device_create(pt1video_class,
+			      NULL,
+			      MKDEV(MAJOR(dev_conf->dev),
+				    (MINOR(dev_conf->dev) + lp)),
+			      "pt1video%u",
+			      MINOR(dev_conf->dev) + lp +
+			      dev_conf->card_number * MAX_CHANNEL);
 #endif
 
 #if 0
@@ -715,6 +734,7 @@
 		video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1);
 #endif
 	}
+
 	if(pt1_dma_init(pdev, dev_conf) < 0){
 		goto out_err_dma;
 	}
@@ -773,15 +793,18 @@
 				kfree(dev_conf->channel[lp]->buf);
 				kfree(dev_conf->channel[lp]);
 			}
-			device_destroy(pt1video_class, 
-							MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)));
+			device_destroy(pt1video_class,
+				       MKDEV(MAJOR(dev_conf->dev),
+					     (MINOR(dev_conf->dev) + lp)));
 		}
+
 		unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL);
 		writel(0xb0b0000, dev_conf->regs);
 		writel(0, dev_conf->regs + 4);
 		settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF);
 		release_mem_region(dev_conf->mmio_start, dev_conf->mmio_len);
 		iounmap(dev_conf->regs);
+		device[dev_conf->card_number] = NULL;
 		kfree(dev_conf);
 	}
 	pci_set_drvdata(pdev, NULL);
@@ -826,7 +849,7 @@
 static void __exit pt1_pci_cleanup(void)
 {
 	class_destroy(pt1video_class);
-	pci_unregister_driver (&pt1_driver);
+	pci_unregister_driver(&pt1_driver);
 }
 
 module_init(pt1_pci_init);