[PATCH] Request xc3028_release symbol when CONFIG_DVB_CORE_ATTACH is defined

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

 



Hello,

I sent a post a few days ago outlining a crash that I was experiencing
when trying to remove the xc3028_tuner module with the
v4l-dvb-experimental codebase.  I have investigated the issue further
and determined that my previously suggested fix is not sufficient.  With
my previous suggestion, dvb_frontend_detach would still try to call
symbol_put_addr on xc3028_release even though there was no previous
symbol_request call for that symbol.  That would cause the "Used by"
reference counter for xc3028_tuner to become a negative value meaning
that the module could not be unloaded.

The attached patch fixes this by exporting xc3028_release from
xc3028_tuner and then requesting it in cxusb_xc3028_tuner_attach.  This
means that xc3028_tuner cannot be unloaded before dvb_usb_cxusb (or else
dvb_frontend_detach will try to call xc3028_release even though
xc3028_tuner is not loaded).

Daniel
diff -ruN v4l-dvb-experimental.orig/linux/drivers/media/dvb/dvb-usb/cxusb.c v4l-dvb-experimental/linux/drivers/media/dvb/dvb-usb/cxusb.c
--- v4l-dvb-experimental.orig/linux/drivers/media/dvb/dvb-usb/cxusb.c	2007-05-06 18:36:26.000000000 +1000
+++ v4l-dvb-experimental/linux/drivers/media/dvb/dvb-usb/cxusb.c	2007-05-07 03:24:35.480456621 +1000
@@ -448,6 +448,9 @@
 	adap->fe->ops.tuner_ops.ioctl = cxusb_xc3028_ioctl;
 	adap->fe->ops.tuner_ops.dev = adap;
 	dvb_attach(xc3028_attach,&adap->fe->ops.tuner_ops, &adap->dev->i2c_adap, NULL);
+#ifdef CONFIG_DVB_CORE_ATTACH
+	symbol_request(xc3028_release);
+#endif
 	return 0;
 }
 
diff -ruN v4l-dvb-experimental.orig/linux/drivers/media/tuners/xc3028-tuner.c v4l-dvb-experimental/linux/drivers/media/tuners/xc3028-tuner.c
--- v4l-dvb-experimental.orig/linux/drivers/media/tuners/xc3028-tuner.c	2007-05-06 18:36:26.000000000 +1000
+++ v4l-dvb-experimental/linux/drivers/media/tuners/xc3028-tuner.c	2007-05-07 03:21:07.439948871 +1000
@@ -512,14 +512,13 @@
 	return 0;
 }
 
-static int xc3028_release(struct v4l_dvb_tuner_ops *t)
+int xc3028_release(struct v4l_dvb_tuner_ops *t)
 {
 	struct xc3028_priv *priv = t->priv;
 
 	if(priv)
 		kfree(priv);
 	t->priv = NULL;
-	t->release=NULL;
 	return 0;
 }
 
@@ -578,6 +577,7 @@
 }
 
 EXPORT_SYMBOL(xc3028_attach);
+EXPORT_SYMBOL(xc3028_release);
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -ruN v4l-dvb-experimental.orig/linux/drivers/media/tuners/xc3028-tuner.h v4l-dvb-experimental/linux/drivers/media/tuners/xc3028-tuner.h
--- v4l-dvb-experimental.orig/linux/drivers/media/tuners/xc3028-tuner.h	2007-05-06 18:36:26.000000000 +1000
+++ v4l-dvb-experimental/linux/drivers/media/tuners/xc3028-tuner.h	2007-05-07 03:20:01.824003768 +1000
@@ -8,6 +8,7 @@
 
 #if defined(CONFIG_XC3028_TUNER) || (defined(CONFIG_XC3028_TUNER_MODULE) && defined(MODULE))
 extern struct v4l_dvb_tuner_ops *xc3028_attach(struct v4l_dvb_tuner_ops *dev,  struct i2c_adapter *i2c, struct xc3028_config *config);
+int xc3028_release(struct v4l_dvb_tuner_ops *t);
 #else
 static inline struct v4l_dvb_tuner_ops *xc3028_attach(struct v4l_dvb_tuner_ops *dev,
 						      struct i2c_adapter *i2c, struct xc3028_config *config)
_______________________________________________
linux-dvb mailing list
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux