Commit 73ca66b9 authored by Magnus Damm's avatar Magnus Damm Committed by Linus Torvalds

[PATCH] release_firmware() fixes

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: default avatarMagnus Damm <magnus@valinux.co.jp>
Acked-by: default avatarMarcel 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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 454d6fbc
...@@ -234,6 +234,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id ...@@ -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); data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
if (!data->fw_data) { if (!data->fw_data) {
BT_ERR("Can't allocate memory for firmware image"); BT_ERR("Can't allocate memory for firmware image");
release_firmware(firmware);
usb_free_urb(data->urb); usb_free_urb(data->urb);
kfree(data->buffer); kfree(data->buffer);
kfree(data); kfree(data);
......
...@@ -896,9 +896,9 @@ static int nxt2002_init(struct dvb_frontend* fe) ...@@ -896,9 +896,9 @@ static int nxt2002_init(struct dvb_frontend* fe)
} }
ret = nxt2002_load_firmware(fe, fw); ret = nxt2002_load_firmware(fe, fw);
release_firmware(fw);
if (ret) { if (ret) {
printk("nxt2002: Writing firmware to device failed\n"); printk("nxt2002: Writing firmware to device failed\n");
release_firmware(fw);
return ret; return ret;
} }
printk("nxt2002: Firmware upload complete\n"); printk("nxt2002: Firmware upload complete\n");
...@@ -960,9 +960,9 @@ static int nxt2004_init(struct dvb_frontend* fe) ...@@ -960,9 +960,9 @@ static int nxt2004_init(struct dvb_frontend* fe)
} }
ret = nxt2004_load_firmware(fe, fw); ret = nxt2004_load_firmware(fe, fw);
release_firmware(fw);
if (ret) { if (ret) {
printk("nxt2004: Writing firmware to device failed\n"); printk("nxt2004: Writing firmware to device failed\n");
release_firmware(fw);
return ret; return ret;
} }
printk("nxt2004: Firmware upload complete\n"); printk("nxt2004: Firmware upload complete\n");
......
...@@ -437,10 +437,10 @@ static int or51211_init(struct dvb_frontend* fe) ...@@ -437,10 +437,10 @@ static int or51211_init(struct dvb_frontend* fe)
} }
ret = or51211_load_firmware(fe, fw); ret = or51211_load_firmware(fe, fw);
release_firmware(fw);
if (ret) { if (ret) {
printk(KERN_WARNING "or51211: Writing firmware to " printk(KERN_WARNING "or51211: Writing firmware to "
"device failed!\n"); "device failed!\n");
release_firmware(fw);
return ret; return ret;
} }
printk(KERN_INFO "or51211: Firmware upload complete.\n"); printk(KERN_INFO "or51211: Firmware upload complete.\n");
......
...@@ -318,7 +318,6 @@ static int sp8870_init (struct dvb_frontend* fe) ...@@ -318,7 +318,6 @@ static int sp8870_init (struct dvb_frontend* fe)
printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
printk("sp8870: no firmware upload (timeout or file not found?)\n"); printk("sp8870: no firmware upload (timeout or file not found?)\n");
release_firmware(fw);
return -EIO; return -EIO;
} }
...@@ -327,6 +326,7 @@ static int sp8870_init (struct dvb_frontend* fe) ...@@ -327,6 +326,7 @@ static int sp8870_init (struct dvb_frontend* fe)
release_firmware(fw); release_firmware(fw);
return -EIO; return -EIO;
} }
release_firmware(fw);
printk("sp8870: firmware upload complete\n"); printk("sp8870: firmware upload complete\n");
/* enable TS output and interface pins */ /* enable TS output and interface pins */
......
...@@ -520,9 +520,9 @@ static int sp887x_init(struct dvb_frontend* fe) ...@@ -520,9 +520,9 @@ static int sp887x_init(struct dvb_frontend* fe)
} }
ret = sp887x_initial_setup(fe, fw); ret = sp887x_initial_setup(fe, fw);
release_firmware(fw);
if (ret) { if (ret) {
printk("sp887x: writing firmware to device failed\n"); printk("sp887x: writing firmware to device failed\n");
release_firmware(fw);
return ret; return ret;
} }
printk("sp887x: firmware upload complete\n"); printk("sp887x: firmware upload complete\n");
......
...@@ -453,11 +453,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) ...@@ -453,11 +453,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n",
firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
release_firmware(firmware);
return -1; return -1;
} }
if (0 != memcmp(firmware->data, magic, 8)) { if (0 != memcmp(firmware->data, magic, 8)) {
dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n");
release_firmware(firmware);
return -1; return -1;
} }
...@@ -478,6 +480,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) ...@@ -478,6 +480,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
} }
if (checksum) { if (checksum) {
dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n"); dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n");
release_firmware(firmware);
return -1; return -1;
} }
release_firmware(firmware); release_firmware(firmware);
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
#include "orinoco.h" #include "orinoco.h"
static unsigned char *primsym;
static unsigned char *secsym;
static const char primary_fw_name[] = "symbol_sp24t_prim_fw"; static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
static const char secondary_fw_name[] = "symbol_sp24t_sec_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) ...@@ -440,7 +438,7 @@ spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
*/ */
static int static int
spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
const unsigned char *image) const unsigned char *image, int secondary)
{ {
int ret; int ret;
const unsigned char *ptr; const unsigned char *ptr;
...@@ -455,7 +453,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, ...@@ -455,7 +453,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
first_block = (const struct dblock *) ptr; first_block = (const struct dblock *) ptr;
/* Read the PDA */ /* Read the PDA */
if (image != primsym) { if (secondary) {
ret = spectrum_read_pda(hw, pda, sizeof(pda)); ret = spectrum_read_pda(hw, pda, sizeof(pda));
if (ret) if (ret)
return ret; return ret;
...@@ -472,7 +470,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, ...@@ -472,7 +470,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
return ret; return ret;
/* Write the PDA to the adapter */ /* Write the PDA to the adapter */
if (image != primsym) { if (secondary) {
ret = spectrum_apply_pda(hw, first_block, pda); ret = spectrum_apply_pda(hw, first_block, pda);
if (ret) if (ret)
return ret; return ret;
...@@ -487,7 +485,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link, ...@@ -487,7 +485,7 @@ spectrum_dl_image(hermes_t *hw, struct pcmcia_device *link,
ret = hermes_init(hw); ret = hermes_init(hw);
/* hermes_reset() should return 0 with the secondary firmware */ /* hermes_reset() should return 0 with the secondary firmware */
if (image != primsym && ret != 0) if (secondary && ret != 0)
return -ENODEV; return -ENODEV;
/* And this should work with any firmware */ /* And this should work with any firmware */
...@@ -509,33 +507,30 @@ spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link) ...@@ -509,33 +507,30 @@ spectrum_dl_firmware(hermes_t *hw, struct pcmcia_device *link)
const struct firmware *fw_entry; const struct firmware *fw_entry;
if (request_firmware(&fw_entry, primary_fw_name, if (request_firmware(&fw_entry, primary_fw_name,
&handle_to_dev(link)) == 0) { &handle_to_dev(link)) != 0) {
primsym = fw_entry->data;
} else {
printk(KERN_ERR PFX "Cannot find firmware: %s\n", printk(KERN_ERR PFX "Cannot find firmware: %s\n",
primary_fw_name); primary_fw_name);
return -ENOENT; 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 */ /* 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) { if (ret) {
printk(KERN_ERR PFX "Primary firmware download failed\n"); printk(KERN_ERR PFX "Primary firmware download failed\n");
return ret; return ret;
} }
/* Load secondary firmware */ if (request_firmware(&fw_entry, secondary_fw_name,
ret = spectrum_dl_image(hw, link, secsym); &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) { if (ret) {
printk(KERN_ERR PFX "Secondary firmware download failed\n"); printk(KERN_ERR PFX "Secondary firmware download failed\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment