Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: [PATCH] fix oops from removing running dvb_net



HI

I just noticed that latest 05* patch won't compile with 2.4,
so here's the update with modified 05-getif2.patch and also
the joint patch for all patches for the testers to simplify
the patching

Emard
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/b2c2/skystar2.c dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c
--- dvb-kernel.orig/linux/drivers/media/dvb/b2c2/skystar2.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c	2003-12-16 22:56:53.000000000 +0100
@@ -2243,7 +2243,7 @@ static int skystar2_probe(struct pci_dev
 	if (driver_initialize(pdev) != 0)
 		return -ENODEV;
 
-	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name);
+	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name, THIS_MODULE);
 
 	if (dvb_adapter == NULL) {
 		printk("%s: Error registering DVB adapter\n", __FUNCTION__);
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c dvb-kernel/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- dvb-kernel.orig/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2003-12-16 22:56:53.000000000 +0100
@@ -321,7 +321,7 @@ static int __init dvb_bt8xx_load_card( s
 	
 	}
 
-	if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name)) < 0) {
+	if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
 	
 		printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
 		
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dmxdev.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dmxdev.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dmxdev.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dmxdev.c	2003-12-16 22:56:53.000000000 +0100
@@ -250,6 +250,7 @@ static int dvb_dvr_release(struct inode 
 		}
 	}
 	up(&dmxdev->mutex);
+	dvb_device_release(dvbdev);
 	return 0;
 }
 
@@ -992,8 +993,14 @@ static int dvb_demux_release(struct inod
 {
 	struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
 	struct dmxdev *dmxdev = dmxdevfilter->dev;
+	struct dvb_device *dvbdev= dmxdev->dvbdev;
+	int ret;
 
-	return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+	ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+	if (!ret) {
+	        dvb_device_release(dvbdev);
+	}
+	return ret;
 }
 
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c	2003-12-16 22:58:26.000000000 +0100
@@ -79,26 +79,42 @@ static struct dvb_device* dvbdev_find_de
 static int dvb_device_open(struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev;
+	struct file_operations *old_fops;
+	int err = -EOPNOTSUPP;
 	
 	dvbdev = dvbdev_find_device (iminor(inode));
 
-	if (dvbdev && dvbdev->fops) {
-		int err = 0;
-		struct file_operations *old_fops;
-
-		file->private_data = dvbdev;
-		old_fops = file->f_op;
-                file->f_op = fops_get(dvbdev->fops);
-                if(file->f_op->open)
-                        err = file->f_op->open(inode,file);
-                if (err) {
-                        fops_put(file->f_op);
-                        file->f_op = fops_get(old_fops);
-                }
-                fops_put(old_fops);
-                return err;
-	}
-	return -ENODEV;
+	if (!dvbdev)
+		return -ENODEV;
+	if (!dvbdev->fops)
+		return -ENODEV;
+	if (!dvbdev->adapter)
+		return -ENODEV;
+	if (!try_module_get(dvbdev->adapter->module))
+	        return -ENODEV;
+
+	file->private_data = dvbdev;
+	old_fops = file->f_op;
+	file->f_op = fops_get(dvbdev->fops);
+	if(file->f_op->open)
+	       err = file->f_op->open(inode,file);
+	if (err) {
+	        fops_put(file->f_op);
+	        file->f_op = fops_get(old_fops);
+	        module_put(dvbdev->adapter->module);
+	}
+	fops_put(old_fops);
+	return err;
+}
+
+/* Needs to be to drop module count when not 
+ * using dvb_generic_release.
+ */
+void dvb_device_release(struct dvb_device *dvbdev)
+{
+        if (dvbdev && dvbdev->adapter) {
+	        module_put(dvbdev->adapter->module);        
+        }
 }
 
 
@@ -150,6 +166,7 @@ int dvb_generic_release(struct inode *in
 	}
 	
 	dvbdev->users++;
+	dvb_device_release(dvbdev);
 	return 0;
 }
 
@@ -287,7 +304,8 @@ skip:
 }
 
 
-int dvb_register_adapter(struct dvb_adapter **padap, const char *name)
+int dvb_register_adapter(struct dvb_adapter **padap, const char *name,
+			 struct module *module)
 {
 	struct dvb_adapter *adap;
 	int num;
@@ -321,6 +339,7 @@ int dvb_register_adapter(struct dvb_adap
 #endif
 	adap->num = num;
 	adap->name = name;
+	adap->module = module;
 
 	list_add_tail (&adap->list_head, &dvb_adapter_list);
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.h dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.h	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h	2003-12-16 22:56:53.000000000 +0100
@@ -52,6 +52,7 @@ struct dvb_adapter {
 	struct list_head device_list;
 	const char *name;
 	u8 proposed_mac [6];
+	struct module *module;
 };
 
 
@@ -79,7 +80,10 @@ struct dvb_device {
 };
 
 
-extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name);
+extern int dvb_register_adapter (struct dvb_adapter **padap, 
+				 const char *name,
+				 struct module *module);
+
 extern int dvb_unregister_adapter (struct dvb_adapter *adap);
 
 extern int dvb_register_device (struct dvb_adapter *adap,
@@ -92,6 +96,7 @@ extern void dvb_unregister_device (struc
 
 extern int dvb_generic_open (struct inode *inode, struct file *file);
 extern int dvb_generic_release (struct inode *inode, struct file *file);
+extern void dvb_device_release(struct dvb_device *dvbdev);
 extern int dvb_generic_ioctl (struct inode *inode, struct file *file,
 			      unsigned int cmd, unsigned long arg);
 #endif /* #ifndef _DVBDEV_H_ */
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-16 22:56:53.000000000 +0100
@@ -4518,7 +4518,7 @@ static int av7110_attach (struct saa7146
 	DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
 
 	av7110->dev=(struct saa7146_dev *)dev;
-	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
+	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, THIS_MODULE);
 
 	/* the Siemens DVB needs this if you want to have the i2c chips
 	   get recognized before the main driver is fully loaded */
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-av.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-av.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-av.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-av.c	2003-12-16 22:56:53.000000000 +0100
@@ -204,7 +204,7 @@ static int budget_av_attach (struct saa7
 
 	memset(budget_av, 0, sizeof(struct budget_av));
 
-	if ((err = ttpci_budget_init(&budget_av->budget, dev, info))) {
+	if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
 		kfree(budget_av);
 		return err;
 	}
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-ci.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-ci.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-ci.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-ci.c	2003-12-16 22:56:53.000000000 +0100
@@ -250,7 +250,7 @@ static int budget_ci_attach (struct saa7
 
 	DEB_EE(("budget_ci: %p\n", budget_ci));
 
-	if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) {
+	if ((err = ttpci_budget_init (&budget_ci->budget, dev, info, THIS_MODULE))) {
 		kfree (budget_ci);
 		return err;
 	}
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-16 22:56:53.000000000 +0100
@@ -195,7 +195,8 @@ static int master_xfer (struct dvb_i2c_b
 
 int ttpci_budget_init (struct budget *budget,
 		       struct saa7146_dev* dev,
-		       struct saa7146_pci_extension_data *info)
+		       struct saa7146_pci_extension_data *info,
+		       struct module *module)
 {
 	int length = TS_WIDTH*TS_HEIGHT;
 	int ret = 0;
@@ -208,7 +209,7 @@ int ttpci_budget_init (struct budget *bu
 	budget->card = bi;
 	budget->dev = (struct saa7146_dev *) dev;
 
-	dvb_register_adapter(&budget->dvb_adapter, budget->card->name);
+	dvb_register_adapter(&budget->dvb_adapter, budget->card->name, module);
 
 	/* set dd1 stream a & b */
       	saa7146_write(dev, DD1_STREAM_B, 0x00000000);
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-patch.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-patch.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-patch.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-patch.c	2003-12-16 22:56:53.000000000 +0100
@@ -172,7 +172,7 @@ static int budget_patch_attach (struct s
 
         DEB_EE(("budget: %p\n",budget));
 
-        if ((err = ttpci_budget_init (budget, dev, info))) {
+        if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
                 kfree (budget);
                 return err;
         }
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget.c	2003-12-16 22:56:53.000000000 +0100
@@ -154,7 +154,7 @@ static int budget_attach (struct saa7146
 
 	DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
 
-	if ((err = ttpci_budget_init (budget, dev, info))) {
+	if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
 		printk("==> failed\n");
 		kfree (budget);
 		return err;
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.h dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.h	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h	2003-12-16 22:56:53.000000000 +0100
@@ -77,7 +77,9 @@ static struct saa7146_pci_extension_data
 
 extern int ttpci_budget_init (struct budget *budget,
 			      struct saa7146_dev* dev,
-			      struct saa7146_pci_extension_data *info);
+			      struct saa7146_pci_extension_data *info,
+			      struct module *module);
+
 extern int ttpci_budget_deinit (struct budget *budget);
 extern void ttpci_budget_irq10_handler (struct saa7146_dev* dev, u32 *isr);
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c dvb-kernel/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-12-16 22:56:54.000000000 +0100
@@ -1130,7 +1130,8 @@ static int ttusb_probe(struct usb_interf
 	up(&ttusb->sem);
 
 	dvb_register_adapter(&ttusb->adapter,
-			     "Technotrend/Hauppauge Nova-USB");
+			     "Technotrend/Hauppauge Nova-USB", 
+			     THIS_MODULE);
 
 	dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0);
 	dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL,
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c dvb-kernel/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-12-16 21:26:51.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-12-16 22:56:54.000000000 +0100
@@ -951,7 +951,7 @@ static int ttusb_dec_init_dvb(struct ttu
 
 	dprintk("%s\n", __FUNCTION__);
 
-	if ((result = dvb_register_adapter(&dec->adapter, dec->model_name)) < 0) {
+	if ((result = dvb_register_adapter(&dec->adapter, dec->model_name, THIS_MODULE)) < 0) {
 		printk("%s: dvb_register_adapter failed: error %d\n",
 		       __FUNCTION__, result);
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-12 22:22:19.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-13 18:58:46.000000000 +0100
@@ -306,7 +306,7 @@ static int dvb_net_feed_start(struct net
 	return 0;
 }
 
-static void dvb_net_feed_stop(struct net_device *dev)
+static int dvb_net_feed_stop(struct net_device *dev)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int i;
@@ -337,7 +337,11 @@ static void dvb_net_feed_stop(struct net
 		priv->demux->release_section_feed(priv->demux, priv->secfeed);
 		priv->secfeed=0;
 	} else
+	{
 		printk("%s: no feed to stop\n", dev->name);
+		return -1;
+	}
+	return 0;
 }
 
 
@@ -360,7 +364,8 @@ static void wq_set_multicast_list (void 
 	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
-	dvb_net_feed_stop(dev);
+	if(dvb_net_feed_stop(dev))
+		return; // no feed to stop
 
 	priv->rx_mode = RX_MODE_UNI;
 	
@@ -387,8 +392,8 @@ static void wq_set_multicast_list (void 
 		}
 	}
 
-		dvb_net_feed_start(dev);
-	}
+	dvb_net_feed_start(dev);
+}
 
 
 static void dvb_net_set_multicast_list (struct net_device *dev)
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-12 22:22:19.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-13 18:58:46.000000000 +0100
@@ -592,6 +597,11 @@ static int dvb_net_remove_if(struct dvb_
 	if (priv->in_use)
 		return -EBUSY;
 
+	if (netif_running(&dvbnet->device[num]))
+	{
+		printk("dvb_net.c: WARNING attempt to remove netif in use\n");
+		return -EBUSY;
+	}
 	dvb_net_stop(&dvbnet->device[num]);
 	flush_scheduled_work();
 	kfree(priv);
@@ -649,8 +659,11 @@ static int dvb_net_do_ioctl(struct inode
 		struct dvb_net_priv *priv_data;
 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
 
-		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
-		    !dvbnet->state[dvbnetif->if_num])
+		if(dvbnetif->if_num < 0 ||
+		    dvbnetif->if_num >= DVB_NET_DEVICES_MAX)
+			return -EFAULT;
+
+		if(!dvbnet->state[dvbnetif->if_num])
 			return -EFAULT;
 
 		netdev=(struct net_device*)&dvbnet->device[dvbnetif->if_num];
@@ -659,9 +672,22 @@ static int dvb_net_do_ioctl(struct inode
 		break;
 	}
 	case NET_REMOVE_IF:
+	{
+		int deviceno = (int) (long) parg;
+
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		return dvb_net_remove_if(dvbnet, (int) (long) parg);
+
+		if(deviceno < 0 ||
+		   deviceno >= DVB_NET_DEVICES_MAX)
+			return -EFAULT;
+
+		if(!dvbnet->state[deviceno])
+			return -EFAULT;
+
+		return dvb_net_remove_if(dvbnet, deviceno);
+
+	}
 	default:
 		return -EINVAL;
 	}
diff -pur dvb-kernel.orig2/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig2/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-16 22:40:59.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-16 22:51:50.000000000 +0100
@@ -647,9 +647,18 @@ static int dvb_net_do_ioctl(struct inode
 		
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
+		if (!dvbdev)
+			return -ENODEV;
+		if (!dvbdev->adapter)
+			return -ENODEV;
+		if (!try_module_get(dvbdev->adapter->module))
+			return -ENODEV;
 		result=dvb_net_add_if(dvbnet, dvbnetif->pid);
 		if (result<0)
+		{
+			module_put(dvbdev->adapter->module);
 			return result;
+		}
 		dvbnetif->if_num=result;
 		break;
 	}
@@ -674,6 +683,7 @@ static int dvb_net_do_ioctl(struct inode
 	case NET_REMOVE_IF:
 	{
 		int deviceno = (int) (long) parg;
+		int result;
 
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
@@ -685,8 +695,10 @@ static int dvb_net_do_ioctl(struct inode
 		if(!dvbnet->state[deviceno])
 			return -EFAULT;
 
-		return dvb_net_remove_if(dvbnet, deviceno);
-
+		result = dvb_net_remove_if(dvbnet, deviceno);
+		if(result == 0)
+			module_put(dvbdev->adapter->module);
+		return result;
 	}
 	default:
 		return -EINVAL;
diff -pur dvb-kernel.orig2/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig2/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-18 17:21:57.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-18 17:24:05.000000000 +0100
@@ -668,28 +668,36 @@ static int dvb_net_do_ioctl(struct inode
 		struct dvb_net_priv *priv_data;
 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
 
-		if(dvbnetif->if_num < 0 ||
-		    dvbnetif->if_num >= DVB_NET_DEVICES_MAX)
+		if(dvbnetif->if_num >= DVB_NET_DEVICES_MAX)
+			return -EFAULT;
+		if(!dvbnet)
+			return -EFAULT;
+		if(!dvbnet->state)
 			return -EFAULT;
-
 		if(!dvbnet->state[dvbnetif->if_num])
 			return -EFAULT;
-
+		if(!dvbnet->device)
+			return -EFAULT;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		netdev=(struct net_device*)&dvbnet->device[dvbnetif->if_num];
+#else
+		netdev=(struct net_device*)dvbnet->device[dvbnetif->if_num];
+#endif
+		if(!netdev)
+			return -EFAULT;		
 		priv_data=(struct dvb_net_priv*)netdev->priv;
 		dvbnetif->pid=priv_data->pid;
 		break;
 	}
 	case NET_REMOVE_IF:
 	{
-		int deviceno = (int) (long) parg;
+		unsigned int deviceno = (unsigned int) (long) parg;
 		int result;
 
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
-		if(deviceno < 0 ||
-		   deviceno >= DVB_NET_DEVICES_MAX)
+		if(deviceno >= DVB_NET_DEVICES_MAX)
 			return -EFAULT;
 
 		if(!dvbnet->state[deviceno])
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/b2c2/skystar2.c dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c
--- dvb-kernel.orig/linux/drivers/media/dvb/b2c2/skystar2.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c	2003-12-18 17:21:29.000000000 +0100
@@ -2243,7 +2243,7 @@ static int skystar2_probe(struct pci_dev
 	if (driver_initialize(pdev) != 0)
 		return -ENODEV;
 
-	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name);
+	dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name, THIS_MODULE);
 
 	if (dvb_adapter == NULL) {
 		printk("%s: Error registering DVB adapter\n", __FUNCTION__);
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c dvb-kernel/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c
--- dvb-kernel.orig/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c	2003-12-18 17:21:29.000000000 +0100
@@ -321,7 +321,7 @@ static int __init dvb_bt8xx_load_card( s
 	
 	}
 
-	if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name)) < 0) {
+	if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) {
 	
 		printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result);
 		
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dmxdev.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dmxdev.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dmxdev.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dmxdev.c	2003-12-18 17:21:29.000000000 +0100
@@ -250,6 +250,7 @@ static int dvb_dvr_release(struct inode 
 		}
 	}
 	up(&dmxdev->mutex);
+	dvb_device_release(dvbdev);
 	return 0;
 }
 
@@ -992,8 +993,14 @@ static int dvb_demux_release(struct inod
 {
 	struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
 	struct dmxdev *dmxdev = dmxdevfilter->dev;
+	struct dvb_device *dvbdev= dmxdev->dvbdev;
+	int ret;
 
-	return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+	ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
+	if (!ret) {
+	        dvb_device_release(dvbdev);
+	}
+	return ret;
 }
 
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c	2003-12-18 17:24:05.000000000 +0100
@@ -306,7 +306,7 @@ static int dvb_net_feed_start(struct net
 	return 0;
 }
 
-static void dvb_net_feed_stop(struct net_device *dev)
+static int dvb_net_feed_stop(struct net_device *dev)
 {
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 	int i;
@@ -337,7 +337,11 @@ static void dvb_net_feed_stop(struct net
 		priv->demux->release_section_feed(priv->demux, priv->secfeed);
 		priv->secfeed=0;
 	} else
+	{
 		printk("%s: no feed to stop\n", dev->name);
+		return -1;
+	}
+	return 0;
 }
 
 
@@ -360,7 +364,8 @@ static void wq_set_multicast_list (void 
 	struct net_device *dev = data;
 	struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
 
-	dvb_net_feed_stop(dev);
+	if(dvb_net_feed_stop(dev))
+		return; // no feed to stop
 
 	priv->rx_mode = RX_MODE_UNI;
 	
@@ -387,8 +392,8 @@ static void wq_set_multicast_list (void 
 		}
 	}
 
-		dvb_net_feed_start(dev);
-	}
+	dvb_net_feed_start(dev);
+}
 
 
 static void dvb_net_set_multicast_list (struct net_device *dev)
@@ -592,6 +597,11 @@ static int dvb_net_remove_if(struct dvb_
 	if (priv->in_use)
 		return -EBUSY;
 
+	if (netif_running(&dvbnet->device[num]))
+	{
+		printk("dvb_net.c: WARNING attempt to remove netif in use\n");
+		return -EBUSY;
+	}
 	dvb_net_stop(&dvbnet->device[num]);
 	flush_scheduled_work();
 	kfree(priv);
@@ -637,9 +647,18 @@ static int dvb_net_do_ioctl(struct inode
 		
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
+		if (!dvbdev)
+			return -ENODEV;
+		if (!dvbdev->adapter)
+			return -ENODEV;
+		if (!try_module_get(dvbdev->adapter->module))
+			return -ENODEV;
 		result=dvb_net_add_if(dvbnet, dvbnetif->pid);
 		if (result<0)
+		{
+			module_put(dvbdev->adapter->module);
 			return result;
+		}
 		dvbnetif->if_num=result;
 		break;
 	}
@@ -649,19 +668,46 @@ static int dvb_net_do_ioctl(struct inode
 		struct dvb_net_priv *priv_data;
 		struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
 
-		if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
-		    !dvbnet->state[dvbnetif->if_num])
+		if(dvbnetif->if_num >= DVB_NET_DEVICES_MAX)
 			return -EFAULT;
-
+		if(!dvbnet)
+			return -EFAULT;
+		if(!dvbnet->state)
+			return -EFAULT;
+		if(!dvbnet->state[dvbnetif->if_num])
+			return -EFAULT;
+		if(!dvbnet->device)
+			return -EFAULT;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		netdev=(struct net_device*)&dvbnet->device[dvbnetif->if_num];
+#else
+		netdev=(struct net_device*)dvbnet->device[dvbnetif->if_num];
+#endif
+		if(!netdev)
+			return -EFAULT;		
 		priv_data=(struct dvb_net_priv*)netdev->priv;
 		dvbnetif->pid=priv_data->pid;
 		break;
 	}
 	case NET_REMOVE_IF:
+	{
+		unsigned int deviceno = (unsigned int) (long) parg;
+		int result;
+
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		return dvb_net_remove_if(dvbnet, (int) (long) parg);
+
+		if(deviceno >= DVB_NET_DEVICES_MAX)
+			return -EFAULT;
+
+		if(!dvbnet->state[deviceno])
+			return -EFAULT;
+
+		result = dvb_net_remove_if(dvbnet, deviceno);
+		if(result == 0)
+			module_put(dvbdev->adapter->module);
+		return result;
+	}
 	default:
 		return -EINVAL;
 	}
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c.orig
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.c	2003-12-18 17:21:29.000000000 +0100
@@ -79,26 +79,42 @@ static struct dvb_device* dvbdev_find_de
 static int dvb_device_open(struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev;
+	struct file_operations *old_fops;
+	int err = -EOPNOTSUPP;
 	
 	dvbdev = dvbdev_find_device (iminor(inode));
 
-	if (dvbdev && dvbdev->fops) {
-		int err = 0;
-		struct file_operations *old_fops;
-
-		file->private_data = dvbdev;
-		old_fops = file->f_op;
-                file->f_op = fops_get(dvbdev->fops);
-                if(file->f_op->open)
-                        err = file->f_op->open(inode,file);
-                if (err) {
-                        fops_put(file->f_op);
-                        file->f_op = fops_get(old_fops);
-                }
-                fops_put(old_fops);
-                return err;
-	}
-	return -ENODEV;
+	if (!dvbdev)
+		return -ENODEV;
+	if (!dvbdev->fops)
+		return -ENODEV;
+	if (!dvbdev->adapter)
+		return -ENODEV;
+	if (!try_module_get(dvbdev->adapter->module))
+	        return -ENODEV;
+
+	file->private_data = dvbdev;
+	old_fops = file->f_op;
+	file->f_op = fops_get(dvbdev->fops);
+	if(file->f_op->open)
+	       err = file->f_op->open(inode,file);
+	if (err) {
+	        fops_put(file->f_op);
+	        file->f_op = fops_get(old_fops);
+	        module_put(dvbdev->adapter->module);
+	}
+	fops_put(old_fops);
+	return err;
+}
+
+/* Needs to be to drop module count when not 
+ * using dvb_generic_release.
+ */
+void dvb_device_release(struct dvb_device *dvbdev)
+{
+        if (dvbdev && dvbdev->adapter) {
+	        module_put(dvbdev->adapter->module);        
+        }
 }
 
 
@@ -150,6 +166,7 @@ int dvb_generic_release(struct inode *in
 	}
 	
 	dvbdev->users++;
+	dvb_device_release(dvbdev);
 	return 0;
 }
 
@@ -287,7 +304,8 @@ skip:
 }
 
 
-int dvb_register_adapter(struct dvb_adapter **padap, const char *name)
+int dvb_register_adapter(struct dvb_adapter **padap, const char *name,
+			 struct module *module)
 {
 	struct dvb_adapter *adap;
 	int num;
@@ -321,6 +339,7 @@ int dvb_register_adapter(struct dvb_adap
 #endif
 	adap->num = num;
 	adap->name = name;
+	adap->module = module;
 
 	list_add_tail (&adap->list_head, &dvb_adapter_list);
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.h dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvbdev.h	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvbdev.h	2003-12-18 17:21:29.000000000 +0100
@@ -52,6 +52,7 @@ struct dvb_adapter {
 	struct list_head device_list;
 	const char *name;
 	u8 proposed_mac [6];
+	struct module *module;
 };
 
 
@@ -79,7 +80,10 @@ struct dvb_device {
 };
 
 
-extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name);
+extern int dvb_register_adapter (struct dvb_adapter **padap, 
+				 const char *name,
+				 struct module *module);
+
 extern int dvb_unregister_adapter (struct dvb_adapter *adap);
 
 extern int dvb_register_device (struct dvb_adapter *adap,
@@ -92,6 +96,7 @@ extern void dvb_unregister_device (struc
 
 extern int dvb_generic_open (struct inode *inode, struct file *file);
 extern int dvb_generic_release (struct inode *inode, struct file *file);
+extern void dvb_device_release(struct dvb_device *dvbdev);
 extern int dvb_generic_ioctl (struct inode *inode, struct file *file,
 			      unsigned int cmd, unsigned long arg);
 #endif /* #ifndef _DVBDEV_H_ */
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c	2003-12-18 17:21:30.000000000 +0100
@@ -4518,7 +4518,7 @@ static int av7110_attach (struct saa7146
 	DEB_EE(("dev: %p, av7110: %p\n",dev,av7110));
 
 	av7110->dev=(struct saa7146_dev *)dev;
-	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name);
+	dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, THIS_MODULE);
 
 	/* the Siemens DVB needs this if you want to have the i2c chips
 	   get recognized before the main driver is fully loaded */
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-av.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-av.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-av.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-av.c	2003-12-18 17:21:30.000000000 +0100
@@ -204,7 +204,7 @@ static int budget_av_attach (struct saa7
 
 	memset(budget_av, 0, sizeof(struct budget_av));
 
-	if ((err = ttpci_budget_init(&budget_av->budget, dev, info))) {
+	if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
 		kfree(budget_av);
 		return err;
 	}
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-ci.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-ci.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-ci.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-ci.c	2003-12-18 17:21:30.000000000 +0100
@@ -250,7 +250,7 @@ static int budget_ci_attach (struct saa7
 
 	DEB_EE(("budget_ci: %p\n", budget_ci));
 
-	if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) {
+	if ((err = ttpci_budget_init (&budget_ci->budget, dev, info, THIS_MODULE))) {
 		kfree (budget_ci);
 		return err;
 	}
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-12-18 17:21:30.000000000 +0100
@@ -195,7 +195,8 @@ static int master_xfer (struct dvb_i2c_b
 
 int ttpci_budget_init (struct budget *budget,
 		       struct saa7146_dev* dev,
-		       struct saa7146_pci_extension_data *info)
+		       struct saa7146_pci_extension_data *info,
+		       struct module *module)
 {
 	int length = TS_WIDTH*TS_HEIGHT;
 	int ret = 0;
@@ -208,7 +209,7 @@ int ttpci_budget_init (struct budget *bu
 	budget->card = bi;
 	budget->dev = (struct saa7146_dev *) dev;
 
-	dvb_register_adapter(&budget->dvb_adapter, budget->card->name);
+	dvb_register_adapter(&budget->dvb_adapter, budget->card->name, module);
 
 	/* set dd1 stream a & b */
       	saa7146_write(dev, DD1_STREAM_B, 0x00000000);
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-patch.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-patch.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-patch.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-patch.c	2003-12-18 17:21:30.000000000 +0100
@@ -172,7 +172,7 @@ static int budget_patch_attach (struct s
 
         DEB_EE(("budget: %p\n",budget));
 
-        if ((err = ttpci_budget_init (budget, dev, info))) {
+        if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
                 kfree (budget);
                 return err;
         }
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget.c	2003-12-18 17:21:30.000000000 +0100
@@ -154,7 +154,7 @@ static int budget_attach (struct saa7146
 
 	DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
 
-	if ((err = ttpci_budget_init (budget, dev, info))) {
+	if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
 		printk("==> failed\n");
 		kfree (budget);
 		return err;
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.h dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget.h	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h	2003-12-18 17:21:30.000000000 +0100
@@ -77,7 +77,9 @@ static struct saa7146_pci_extension_data
 
 extern int ttpci_budget_init (struct budget *budget,
 			      struct saa7146_dev* dev,
-			      struct saa7146_pci_extension_data *info);
+			      struct saa7146_pci_extension_data *info,
+			      struct module *module);
+
 extern int ttpci_budget_deinit (struct budget *budget);
 extern void ttpci_budget_irq10_handler (struct saa7146_dev* dev, u32 *isr);
 
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c dvb-kernel/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2003-12-18 17:21:30.000000000 +0100
@@ -1130,7 +1130,8 @@ static int ttusb_probe(struct usb_interf
 	up(&ttusb->sem);
 
 	dvb_register_adapter(&ttusb->adapter,
-			     "Technotrend/Hauppauge Nova-USB");
+			     "Technotrend/Hauppauge Nova-USB", 
+			     THIS_MODULE);
 
 	dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0);
 	dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL,
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c dvb-kernel/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-12-18 17:16:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-12-18 17:21:30.000000000 +0100
@@ -951,7 +951,7 @@ static int ttusb_dec_init_dvb(struct ttu
 
 	dprintk("%s\n", __FUNCTION__);
 
-	if ((result = dvb_register_adapter(&dec->adapter, dec->model_name)) < 0) {
+	if ((result = dvb_register_adapter(&dec->adapter, dec->model_name, THIS_MODULE)) < 0) {
 		printk("%s: dvb_register_adapter failed: error %d\n",
 		       __FUNCTION__, result);
 

Home | Main Index | Thread Index