]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] fix module reference counting in zoran driver
authorAndrew Morton <akpm@osdl.org>
Thu, 26 Feb 2004 00:18:11 +0000 (16:18 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 26 Feb 2004 00:18:11 +0000 (16:18 -0800)
From: Christoph Hellwig <hch@lst.de>

Take a reference before calling into the module and release it after we're
done.  Also remove the useless (and wrong) refcounting in videocodec -
symbols from this module are used by other modules if we call into those
functions so it can't be unloaded anyway.

We really need to add a debug check to tip all those
try_module_get(THIS_MODULE) callers..

drivers/media/video/videocodec.c
drivers/media/video/videocodec.h
drivers/media/video/zr36016.c
drivers/media/video/zr36050.c
drivers/media/video/zr36060.c

index 61d17ed4f008cebde967afff8e717f088a8da159..f7700bbf4ba043cbc62f81da0c1192cfecef9407 100644 (file)
@@ -108,13 +108,17 @@ videocodec_attach (struct videocodec_master *master)
                if ((master->flags & h->codec->flags) == master->flags) {
                        dprintk(4, "videocodec_attach: try '%s'\n",
                                h->codec->name);
+
+                       if (!try_module_get(h->codec->owner))
+                               return NULL;
+
                        codec =
                            kmalloc(sizeof(struct videocodec), GFP_KERNEL);
                        if (!codec) {
                                dprintk(1,
                                        KERN_ERR
                                        "videocodec_attach: no mem\n");
-                               return NULL;
+                               goto out_module_put;
                        }
                        memcpy(codec, h->codec, sizeof(struct videocodec));
 
@@ -132,26 +136,12 @@ videocodec_attach (struct videocodec_master *master)
                                        dprintk(1,
                                                KERN_ERR
                                                "videocodec_attach: no memory\n");
-                                       kfree(codec);
-                                       return NULL;
+                                       goto out_kfree;
                                }
                                memset(ptr, 0,
                                       sizeof(struct attached_list));
                                ptr->codec = codec;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-                               MOD_INC_USE_COUNT;
-#else
-                               if (!try_module_get(THIS_MODULE)) {
-                                       dprintk(1,
-                                               KERN_ERR
-                                               "videocodec: failed to increment usecount\n");
-                                       kfree(codec);
-                                       kfree(ptr);
-                                       return NULL;
-                               }
-#endif
-
                                a = h->list;
                                if (!a) {
                                        h->list = ptr;
@@ -177,6 +167,12 @@ videocodec_attach (struct videocodec_master *master)
 
        dprintk(1, KERN_ERR "videocodec_attach: no codec found!\n");
        return NULL;
+
+ out_module_put:
+       module_put(h->codec->owner);
+ out_kfree:
+       kfree(codec);
+       return NULL;
 }
 
 int
@@ -228,16 +224,10 @@ videocodec_detach (struct videocodec *codec)
                                        dprintk(4,
                                                "videocodec: delete middle\n");
                                }
+                               module_put(a->codec->owner);
                                kfree(a->codec);
                                kfree(a);
                                h->attached -= 1;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-                               MOD_DEC_USE_COUNT;
-#else
-                               module_put(THIS_MODULE);
-#endif
-
                                return 0;
                        }
                        prev = a;
@@ -274,18 +264,6 @@ videocodec_register (const struct videocodec *codec)
        memset(ptr, 0, sizeof(struct codec_list));
        ptr->codec = codec;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       MOD_INC_USE_COUNT;
-#else
-       if (!try_module_get(THIS_MODULE)) {
-               dprintk(1,
-                       KERN_ERR
-                       "videocodec: failed to increment module count\n");
-               kfree(ptr);
-               return -ENODEV;
-       }
-#endif
-
        if (!h) {
                codeclist_top = ptr;
                dprintk(4, "videocodec: hooked in as first element\n");
@@ -342,13 +320,6 @@ videocodec_unregister (const struct videocodec *codec)
                                        "videocodec: delete middle element\n");
                        }
                        kfree(h);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-                       MOD_DEC_USE_COUNT;
-#else
-                       module_put(THIS_MODULE);
-#endif
-
                        return 0;
                }
                prev = h;
index 848022a904247e4b60177f01a4f4f23bd5bb86b9..6541aa0698161f1ef61e93b9fb7ee1ed29da58fa 100644 (file)
@@ -249,6 +249,7 @@ struct tvnorm {
 };
 
 struct videocodec {
+       struct module *owner;
        /* -- filled in by slave device during register -- */
        char name[32];
        unsigned long magic;    /* may be used for client<->master attaching */
index f0fdbbc07148b599d03d9049a71090d9714fb903..ceb83bd57c395d2b72fc0d32f03e916f826a7715 100644 (file)
@@ -422,12 +422,6 @@ zr36016_unset (struct videocodec *codec)
                codec->data = NULL;
 
                zr36016_codecs--;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               MOD_DEC_USE_COUNT;
-#else
-               module_put(THIS_MODULE);
-#endif
-
                return 0;
        }
 
@@ -470,19 +464,6 @@ zr36016_setup (struct videocodec *codec)
        ptr->num = zr36016_codecs++;
        ptr->codec = codec;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       MOD_INC_USE_COUNT;
-#else
-       if (!try_module_get(THIS_MODULE)) {
-               dprintk(1,
-                       KERN_ERR
-                       "zr36016: failed to increase module use count\n");
-               kfree(ptr);
-               zr36016_codecs--;
-               return -ENODEV;
-       }
-#endif
-
        //testing
        res = zr36016_basic_test(ptr);
        if (res < 0) {
@@ -504,6 +485,7 @@ zr36016_setup (struct videocodec *codec)
 }
 
 static const struct videocodec zr36016_codec = {
+       .owner = THIS_MODULE,
        .name = "zr36016",
        .magic = 0L,            // magic not used
        .flags =
index be09ffccc47a9f71299c98bae8fbc131e0608fbc..aa09a9297435f6aa03e77608b7a66b5463c136dc 100644 (file)
@@ -737,12 +737,6 @@ zr36050_unset (struct videocodec *codec)
                codec->data = NULL;
 
                zr36050_codecs--;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               MOD_DEC_USE_COUNT;
-#else
-               module_put(THIS_MODULE);
-#endif
-
                return 0;
        }
 
@@ -785,19 +779,6 @@ zr36050_setup (struct videocodec *codec)
        ptr->num = zr36050_codecs++;
        ptr->codec = codec;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       MOD_INC_USE_COUNT;
-#else
-       if (!try_module_get(THIS_MODULE)) {
-               dprintk(1,
-                       KERN_ERR
-                       "zr36050: failed to increase module use count\n");
-               kfree(ptr);
-               zr36050_codecs--;
-               return -ENODEV;
-       }
-#endif
-
        //testing
        res = zr36050_basic_test(ptr);
        if (res < 0) {
@@ -826,6 +807,7 @@ zr36050_setup (struct videocodec *codec)
 }
 
 static const struct videocodec zr36050_codec = {
+       .owner = THIS_MODULE,
        .name = "zr36050",
        .magic = 0L,            // magic not used
        .flags =
index 41ae711a6e17dd1d1f520d2d887be891bf5be7df..2d582a38dada297caf1e2129a23fed6a683def25 100644 (file)
@@ -868,12 +868,6 @@ zr36060_unset (struct videocodec *codec)
                codec->data = NULL;
 
                zr36060_codecs--;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-               MOD_DEC_USE_COUNT;
-#else
-               module_put(THIS_MODULE);
-#endif
-
                return 0;
        }
 
@@ -916,19 +910,6 @@ zr36060_setup (struct videocodec *codec)
        ptr->num = zr36060_codecs++;
        ptr->codec = codec;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-       MOD_INC_USE_COUNT;
-#else
-       if (!try_module_get(THIS_MODULE)) {
-               dprintk(1,
-                       KERN_ERR
-                       "zr36060: failed to increase module use count\n");
-               kfree(ptr);
-               zr36060_codecs--;
-               return -ENODEV;
-       }
-#endif
-
        //testing
        res = zr36060_basic_test(ptr);
        if (res < 0) {
@@ -958,6 +939,7 @@ zr36060_setup (struct videocodec *codec)
 }
 
 static const struct videocodec zr36060_codec = {
+       .owner = THIS_MODULE,
        .name = "zr36060",
        .magic = 0L,            // magic not used
        .flags =