[PATCH] release_firmware() fixes
authorMagnus Damm <magnus@valinux.co.jp>
Mon, 10 Jul 2006 11:44:09 +0000 (04:44 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 10 Jul 2006 20:24:15 +0000 (13:24 -0700)
Use release_firmware() to free requested resources.

According to Documentation/firmware_class/README the request_firmware()
call should be followed by a release_firmware().  Some drivers do not
however free the firmware previously allocated with request_firmware().
This patch tries to fix this by making sure that release_firmware() is used
as expected.

Signed-off-by: Magnus Damm <magnus@valinux.co.jp>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/bluetooth/bcm203x.c
drivers/media/dvb/frontends/nxt200x.c
drivers/media/dvb/frontends/or51211.c
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/net/wireless/spectrum_cs.c

index 6f67141f4de0fbcc3b0d5461fb0a7766b7e627ff..13ba729cdd57445821dbe4bb5bf92f1dd1d4ac07 100644 (file)
@@ -234,6 +234,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
        data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
        if (!data->fw_data) {
                BT_ERR("Can't allocate memory for firmware image");
+               release_firmware(firmware);
                usb_free_urb(data->urb);
                kfree(data->buffer);
                kfree(data);
index 55671cb5255e0aa6972560638cfff7e55552334d..87c286ee6a00a2dbef8094ad1174a45debb1b320 100644 (file)
@@ -896,9 +896,9 @@ static int nxt2002_init(struct dvb_frontend* fe)
        }
 
        ret = nxt2002_load_firmware(fe, fw);
+       release_firmware(fw);
        if (ret) {
                printk("nxt2002: Writing firmware to device failed\n");
-               release_firmware(fw);
                return ret;
        }
        printk("nxt2002: Firmware upload complete\n");
@@ -960,9 +960,9 @@ static int nxt2004_init(struct dvb_frontend* fe)
        }
 
        ret = nxt2004_load_firmware(fe, fw);
+       release_firmware(fw);
        if (ret) {
                printk("nxt2004: Writing firmware to device failed\n");
-               release_firmware(fw);
                return ret;
        }
        printk("nxt2004: Firmware upload complete\n");
index 26bed616fabec1c1293e10b7ade29940ee443ad5..2bf124b5368931da77a2320acd4c471e337a3087 100644 (file)
@@ -437,10 +437,10 @@ static int or51211_init(struct dvb_frontend* fe)
                }
 
                ret = or51211_load_firmware(fe, fw);
+               release_firmware(fw);
                if (ret) {
                        printk(KERN_WARNING "or51211: Writing firmware to "
                               "device failed!\n");
-                       release_firmware(fw);
                        return ret;
                }
                printk(KERN_INFO "or51211: Firmware upload complete.\n");
index 44ec5b9a469580b943c3f92ca1bcbfd6163f6171..d98fd5c2e13e12e6a1dc1f17253e4f4d7de71143 100644 (file)
@@ -318,7 +318,6 @@ static int sp8870_init (struct dvb_frontend* fe)
        printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
        if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
                printk("sp8870: no firmware upload (timeout or file not found?)\n");
-               release_firmware(fw);
                return -EIO;
        }
 
@@ -327,6 +326,7 @@ static int sp8870_init (struct dvb_frontend* fe)
                release_firmware(fw);
                return -EIO;
        }
+       release_firmware(fw);
        printk("sp8870: firmware upload complete\n");
 
        /* enable TS output and interface pins */
index b0a2b02f660869f2724aedb46e45c0b3e8e08a22..5c2f8f4e0ae554873a9ba9b8f1443070422b72d7 100644 (file)
@@ -520,9 +520,9 @@ static int sp887x_init(struct dvb_frontend* fe)
                }
 
                ret = sp887x_initial_setup(fe, fw);
+               release_firmware(fw);
                if (ret) {
                        printk("sp887x: writing firmware to device failed\n");
-                       release_firmware(fw);
                        return ret;
                }
                printk("sp887x: firmware upload complete\n");
index 349632b48e931a2dff360965703754ba0a3b1d19..b60177f173c3c1162726ca3da7eaa105781c8043 100644 (file)
@@ -453,11 +453,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
        if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
                dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
                        firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
+               release_firmware(firmware);
                return -1;
        }
 
        if (0 != memcmp(firmware->data, magic, 8)) {
                dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
+               release_firmware(firmware);
                return -1;
        }
 
@@ -478,6 +480,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
        }
        if (checksum) {
                dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
+               release_firmware(firmware);
                return -1;
        }
        release_firmware(firmware);
index 15465278c789ed607e154775ccb55a3dcbc20f1e..7f78b7801fb3de996a2ad1dff87cce905904efd7 100644 (file)
@@ -34,8 +34,6 @@
 
 #include "orinoco.h"
 
-static unsigned char *primsym;
-static unsigned char *secsym;
 static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
 static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
 
@@ -440,7 +438,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
  */
 static int
 spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
-                 const unsigned char *image)
+                 const unsigned char *image, int secondary)
 {
        int ret;
        const unsigned char *ptr;
@@ -455,7 +453,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
        first_block = (const struct dblock *) ptr;
 
        /* Read the PDA */
-       if (image != primsym) {
+       if (secondary) {
                ret = spectrum_read_pda(hw, pda, sizeof(pda));
                if (ret)
                        return ret;
@@ -472,7 +470,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
                return ret;
 
        /* Write the PDA to the adapter */
-       if (image != primsym) {
+       if (secondary) {
                ret = spectrum_apply_pda(hw, first_block, pda);
                if (ret)
                        return ret;
@@ -487,7 +485,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
        ret = hermes_init(hw);
 
        /* hermes_reset() should return 0 with the secondary firmware */
-       if (image != primsym && ret != 0)
+       if (secondary && ret != 0)
                return -ENODEV;
 
        /* And this should work with any firmware */
@@ -509,33 +507,30 @@ spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link)
        const struct firmware *fw_entry;
 
        if (request_firmware(&fw_entry, primary_fw_name,
-                            &handle_to_dev(link)) == 0) {
-               primsym = fw_entry->data;
-       } else {
+                            &handle_to_dev(link)) != 0) {
                printk(KERN_ERR PFX "Cannot find firmware: %s\n",
                       primary_fw_name);
                return -ENOENT;
        }
 
-       if (request_firmware(&fw_entry, secondary_fw_name,
-                            &handle_to_dev(link)) == 0) {
-               secsym = fw_entry->data;
-       } else {
-               printk(KERN_ERR PFX "Cannot find firmware: %s\n",
-                      secondary_fw_name);
-               return -ENOENT;
-       }
-
        /* Load primary firmware */
-       ret = spectrum_dl_image(hw, link, primsym);
+       ret = spectrum_dl_image(hw, link, fw_entry->data, 0);
+       release_firmware(fw_entry);
        if (ret) {
                printk(KERN_ERR PFX "Primary firmware download failed\n");
                return ret;
        }
 
-       /* Load secondary firmware */
-       ret = spectrum_dl_image(hw, link, secsym);
+       if (request_firmware(&fw_entry, secondary_fw_name,
+                            &handle_to_dev(link)) != 0) {
+               printk(KERN_ERR PFX "Cannot find firmware: %s\n",
+                      secondary_fw_name);
+               return -ENOENT;
+       }
 
+       /* Load secondary firmware */
+       ret = spectrum_dl_image(hw, link, fw_entry->data, 1);
+       release_firmware(fw_entry);
        if (ret) {
                printk(KERN_ERR PFX "Secondary firmware download failed\n");
        }