The patch titled release_firmware() fixes has been added to the -mm tree. Its filename is release_firmware-fixes.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: release_firmware() fixes From: Magnus Damm <magnus@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> Cc: Marcel Holtmann <marcel@xxxxxxxxxxxx> Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxx> Cc: "John W. Linville" <linville@xxxxxxxxxxxxx> Cc: Greg KH <greg@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- drivers/bluetooth/bcm203x.c | 1 drivers/media/dvb/frontends/nxt200x.c | 4 +- drivers/media/dvb/frontends/or51211.c | 2 - drivers/media/dvb/frontends/sp8870.c | 2 - drivers/media/dvb/frontends/sp887x.c | 2 - drivers/media/video/cx88/cx88-blackbird.c | 3 + drivers/net/wireless/spectrum_cs.c | 37 ++++++++------------ 7 files changed, 25 insertions(+), 26 deletions(-) diff -puN drivers/bluetooth/bcm203x.c~release_firmware-fixes drivers/bluetooth/bcm203x.c --- a/drivers/bluetooth/bcm203x.c~release_firmware-fixes +++ a/drivers/bluetooth/bcm203x.c @@ -234,6 +234,7 @@ static int bcm203x_probe(struct usb_inte 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); diff -puN drivers/media/dvb/frontends/nxt200x.c~release_firmware-fixes drivers/media/dvb/frontends/nxt200x.c --- a/drivers/media/dvb/frontends/nxt200x.c~release_firmware-fixes +++ a/drivers/media/dvb/frontends/nxt200x.c @@ -896,9 +896,9 @@ static int nxt2002_init(struct dvb_front } 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_front } 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"); diff -puN drivers/media/dvb/frontends/or51211.c~release_firmware-fixes drivers/media/dvb/frontends/or51211.c --- a/drivers/media/dvb/frontends/or51211.c~release_firmware-fixes +++ a/drivers/media/dvb/frontends/or51211.c @@ -437,10 +437,10 @@ static int or51211_init(struct dvb_front } 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"); diff -puN drivers/media/dvb/frontends/sp8870.c~release_firmware-fixes drivers/media/dvb/frontends/sp8870.c --- a/drivers/media/dvb/frontends/sp8870.c~release_firmware-fixes +++ a/drivers/media/dvb/frontends/sp8870.c @@ -318,7 +318,6 @@ static int sp8870_init (struct dvb_front 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_front release_firmware(fw); return -EIO; } + release_firmware(fw); printk("sp8870: firmware upload complete\n"); /* enable TS output and interface pins */ diff -puN drivers/media/dvb/frontends/sp887x.c~release_firmware-fixes drivers/media/dvb/frontends/sp887x.c --- a/drivers/media/dvb/frontends/sp887x.c~release_firmware-fixes +++ a/drivers/media/dvb/frontends/sp887x.c @@ -520,9 +520,9 @@ static int sp887x_init(struct dvb_fronte } 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"); diff -puN drivers/media/video/cx88/cx88-blackbird.c~release_firmware-fixes drivers/media/video/cx88/cx88-blackbird.c --- a/drivers/media/video/cx88/cx88-blackbird.c~release_firmware-fixes +++ a/drivers/media/video/cx88/cx88-blackbird.c @@ -453,11 +453,13 @@ static int blackbird_load_firmware(struc 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(struc } if (checksum) { dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n"); + release_firmware(firmware); return -1; } release_firmware(firmware); diff -puN drivers/net/wireless/spectrum_cs.c~release_firmware-fixes drivers/net/wireless/spectrum_cs.c --- a/drivers/net/wireless/spectrum_cs.c~release_firmware-fixes +++ a/drivers/net/wireless/spectrum_cs.c @@ -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 */ 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 p 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 p 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 p 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, struc 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"); } _ Patches currently in -mm which might be from magnus@xxxxxxxxxxxxx are release_firmware-fixes.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html