[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: 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>
This commit is contained in:
parent
454d6fbc48
commit
73ca66b97b
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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 @@
|
||||||
|
|
||||||
#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)
|
||||||
*/
|
*/
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue