Mailing List archive

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

[linux-dvb] [PATCH] Frontend module ref count on open.



Hi,

I've attached a patch which fixes the problem where a program has the frontend 
device open, and the frontend module is removed. I've only fixed the 
frontends which already has been converted to the kernel i2c layer, as the 
rest will be forced to provide the dvb-core with module info when they are 
converted, and thus get's this fix as a bonus.

The linenumbers of this patch will be off, but it's quite small, and should be 
easy to apply by hand, what I really wanted to know was if this is a ok 
approach to solve the problem?

Kenneth
Index: dvb-core/dvb_frontend.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.c,v
retrieving revision 1.80
diff -u -r1.80 dvb_frontend.c
--- dvb-core/dvb_frontend.c	14 May 2004 09:55:27 -0000	1.80
+++ dvb-core/dvb_frontend.c	11 Jul 2004 00:47:25 -0000
@@ -835,6 +840,9 @@
 		fe->events.eventr = fe->events.eventw = 0;
 	}
 
+	if (!ret && fe->frontend.module)
+		try_module_get(fe->frontend.module);
+
 	return ret;
 }
 
@@ -843,13 +851,19 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend_data *fe = dvbdev->priv;
+	int ret = 0;
 
 	dprintk ("%s\n", __FUNCTION__);
 
 	if ((file->f_flags & O_ACCMODE) != O_RDONLY)
 		fe->release_jiffies = jiffies;
 
-	return dvb_generic_release (inode, file);
+	ret = dvb_generic_release (inode, file);
+
+	if (!ret && fe->frontend.module)
+		module_put(fe->frontend.module);
+
+	return ret;
 }
 
 
@@ -1172,7 +1186,8 @@
 				     unsigned int cmd, void *arg),
 		       struct dvb_adapter *dvb_adapter,
 		       void *data,
-		       struct dvb_frontend_info *info)
+		       struct dvb_frontend_info *info,
+		       struct module *module)
 {
 	struct list_head *entry;
 	struct dvb_frontend_data *fe;
@@ -1207,6 +1222,7 @@
 	fe->frontend.dvb_adapter = dvb_adapter;
 	fe->frontend.i2c = NULL;
 	fe->frontend.data = data;
+	fe->frontend.module = module;
 	fe->info = info;
 	fe->inversion = INVERSION_OFF;
 
Index: dvb-core/dvb_frontend.h
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_frontend.h,v
retrieving revision 1.11
diff -u -r1.11 dvb_frontend.h
--- dvb-core/dvb_frontend.h	3 May 2004 11:15:31 -0000	1.11
+++ dvb-core/dvb_frontend.h	11 Jul 2004 00:47:27 -0000
@@ -54,6 +54,7 @@
 	void *before_after_data;   /*  can be used by hardware module... */
 	void *notifier_data;       /*  can be used by hardware module... */
 	void *data;                /*  can be used by hardware module... */
+	struct module *module;
 	
 	struct dvb_i2c_bus *i2c;	/* legacy cruft, currently fe drivers depend on this */
 };
@@ -94,15 +95,15 @@
 
 extern int
 dvb_register_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
-				     unsigned int cmd, void *arg),
-		       struct dvb_adapter *dvb_adapter,
-		       void *data,
-		       struct dvb_frontend_info *info);
+					 unsigned int cmd, void *arg),
+			   struct dvb_adapter *dvb_adapter,
+			   void *data, struct dvb_frontend_info *info,
+			   struct module *module);
 
 extern int
 dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,
-				       unsigned int cmd, void *arg),
-			 struct dvb_adapter *dvb_adapter);
+					   unsigned int cmd, void *arg),
+			     struct dvb_adapter *dvb_adapter);
 
 
 /**
Index: frontends/alps_tdlb7.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/alps_tdlb7.c,v
retrieving revision 1.23
diff -u -r1.23 alps_tdlb7.c
--- frontends/alps_tdlb7.c	23 Jun 2004 10:34:45 -0000	1.23
+++ frontends/alps_tdlb7.c	11 Jul 2004 00:47:34 -0000
@@ -659,7 +659,9 @@
 		goto out;
 	}
 
-	ret = dvb_register_frontend_new (tdlb7_ioctl, state->dvb, (void*) state, &tdlb7_info);
+	ret = dvb_register_frontend_new (tdlb7_ioctl, state->dvb,
+					 (void*) state, &tdlb7_info,
+					 THIS_MODULE);
 	if (ret) {
 		printk("tdlb7: registering frontend to dvb-core failed.\n");
 		release_firmware(fw);
Index: frontends/alps_tdmb7.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/alps_tdmb7.c,v
retrieving revision 1.26
diff -u -r1.26 alps_tdmb7.c
--- frontends/alps_tdmb7.c	22 Jun 2004 13:53:59 -0000	1.26
+++ frontends/alps_tdmb7.c	11 Jul 2004 00:47:43 -0000
@@ -442,7 +442,8 @@
 
 	BUG_ON(!state->dvb);
 
-	ret = dvb_register_frontend_new (tdmb7_ioctl, state->dvb, state, &tdmb7_info);
+	ret = dvb_register_frontend_new (tdmb7_ioctl, state->dvb,
+					 state, &tdmb7_info, THIS_MODULE);
 	if (ret) {
 		i2c_detach_client(client);
 		kfree(state);
Index: frontends/at76c651.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/at76c651.c,v
retrieving revision 1.17
diff -u -r1.17 at76c651.c
--- frontends/at76c651.c	23 Jun 2004 12:30:39 -0000	1.17
+++ frontends/at76c651.c	11 Jul 2004 00:47:47 -0000
@@ -487,7 +487,8 @@
 
 	BUG_ON(!state->dvb);
 
-	ret = dvb_register_frontend_new(at76c651_ioctl, state->dvb, state, &at76c651_info);
+	ret = dvb_register_frontend_new(at76c651_ioctl, state->dvb, state,
+					&at76c651_info, THIS_MODULE);
 	if (ret) {
 		i2c_detach_client(client);
 		kfree(client);
Index: frontends/sp887x.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/sp887x.c,v
retrieving revision 1.12
diff -u -r1.12 sp887x.c
--- frontends/sp887x.c	22 Jun 2004 13:49:15 -0000	1.12
+++ frontends/sp887x.c	11 Jul 2004 00:47:52 -0000
@@ -622,7 +622,9 @@
 		goto out;
 	}
 
-	ret = dvb_register_frontend_new (sp887x_ioctl, state->dvb, (void*) state, &sp887x_info);
+	ret = dvb_register_frontend_new (sp887x_ioctl, state->dvb,
+					 (void*) state, &sp887x_info,
+					 THIS_MODULE);
 	if (ret) {
 		printk("sp887x: registering frontend to dvb-core failed.\n");
 		goto out;
Index: frontends/stv0299.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/stv0299.c,v
retrieving revision 1.50
diff -u -r1.50 stv0299.c
--- frontends/stv0299.c	24 Jun 2004 10:43:54 -0000	1.50
+++ frontends/stv0299.c	11 Jul 2004 00:48:06 -0000
@@ -1395,7 +1399,9 @@
 	
 	BUG_ON(!state->dvb);
 
-	ret = dvb_register_frontend_new (uni0299_ioctl, state->dvb, (void*) state, &uni0299_info);
+	ret = dvb_register_frontend_new (uni0299_ioctl, state->dvb,
+					 (void*) state, &uni0299_info,
+					 THIS_MODULE);
 	if (ret) {
 		i2c_detach_client(client);
 		kfree(client);
Index: frontends/tda1004x.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/tda1004x.c,v
retrieving revision 1.33
diff -u -r1.33 tda1004x.c
--- frontends/tda1004x.c	13 May 2004 10:52:08 -0000	1.33
+++ frontends/tda1004x.c	11 Jul 2004 00:48:19 -0000
@@ -1503,7 +1503,9 @@
 			goto out;
 		}
 
-		ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10045h_info);
+		ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb,
+						 (void*) state, &tda10045h_info,
+						 THIS_MODULE);
 		break;
 	case FE_TYPE_TDA10046H:
 		state->dspCodeCounterReg = TDA10046H_CODE_CPT;
@@ -1516,7 +1518,9 @@
 			goto out;
 		}
 
-		ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb, (void*) state, &tda10046h_info);
+		ret = dvb_register_frontend_new (tda1004x_ioctl, state->dvb,
+						 (void*) state, &tda10046h_info,
+						 THIS_MODULE);
 		break;
 	default:
 		BUG_ON(1);
Index: frontends/ves1x93.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/ves1x93.c,v
retrieving revision 1.12
diff -u -r1.12 ves1x93.c
--- frontends/ves1x93.c	22 Jun 2004 14:28:03 -0000	1.12
+++ frontends/ves1x93.c	11 Jul 2004 00:48:23 -0000
@@ -638,7 +638,9 @@
 
 	BUG_ON(!state->dvb);
 
-	ret = dvb_register_frontend_new (ves1x93_ioctl, state->dvb, (void*) state, &ves1x93_info);
+	ret = dvb_register_frontend_new (ves1x93_ioctl, state->dvb,
+					 (void*) state, &ves1x93_info,
+					 THIS_MODULE);
 	if (ret) {
 		i2c_detach_client(client);
 		kfree(client);

Home | Main Index | Thread Index