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