Re: Bug#244207: kernel-source-2.6.5: mwave gives warning on suspend

From: Herbert Xu
Date: Sat Apr 17 2004 - 07:25:28 EST


On Sat, Apr 17, 2004 at 12:48:50PM +0100, Russell King wrote:
>
> And that's all it does. It doesn't stop the oops which potentically can
> happen when the struct device is freed (by the module being unloaded)
> while there is still a reference to the struct device.

You're quite right. Even worse, there was an memset in the init
function which set the release function back to NULL :)

This patch should be better.

Cheers,
--
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Index: drivers/char/mwave/mwavedd.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/drivers/char/mwave/mwavedd.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 mwavedd.c
--- a/drivers/char/mwave/mwavedd.c 28 Sep 2003 04:44:12 -0000 1.1.1.7
+++ b/drivers/char/mwave/mwavedd.c 17 Apr 2004 12:20:07 -0000
@@ -470,7 +470,18 @@
* sysfs support <paulsch@xxxxxxxxxx>
*/

-struct device mwave_device;
+static void mwave_device_release(struct device *dev)
+{
+ pMWAVE_DEVICE_DATA pDrvData = &mwave_s_mdd;
+
+ if (pDrvData->device_registered)
+ module_put(THIS_MODULE);
+}
+
+static struct device mwave_device = {
+ .bus_id = "mwave",
+ .release = mwave_device_release,
+};

/* Prevent code redundancy, create a macro for mwave_show_* functions. */
#define mwave_show_function(attr_name, format_string, field) \
@@ -639,11 +650,9 @@
/* uart is registered */

/* sysfs */
- memset(&mwave_device, 0, sizeof (struct device));
- snprintf(mwave_device.bus_id, BUS_ID_SIZE, "mwave");
-
if (device_register(&mwave_device))
goto cleanup_error;
+ __module_get(THIS_MODULE);
pDrvData->device_registered = TRUE;
for (i = 0; i < ARRAY_SIZE(mwave_dev_attrs); i++) {
if(device_create_file(&mwave_device, mwave_dev_attrs[i])) {