diff options
Diffstat (limited to 'debian/patches/bugfix')
34 files changed, 4870 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/bpftool-fix-version-string-in-recursive-builds.patch b/debian/patches/bugfix/all/bpftool-fix-version-string-in-recursive-builds.patch new file mode 100644 index 000000000..3f2d75a6a --- /dev/null +++ b/debian/patches/bugfix/all/bpftool-fix-version-string-in-recursive-builds.patch @@ -0,0 +1,30 @@ +From: Ben Hutchings <benh@debian.org> +Date: Fri, 14 Aug 2020 00:43:54 +0100 +Subject: bpftool: Fix version string in recursive builds +Forwarded: https://lore.kernel.org/bpf/20200813235837.GA497088@decadent.org.uk/T/#u + +When bpftool is built as part of a Debian package build, which itself +uses make, "bpftool version" shows: + + bpftool vmake[4]: Entering directory /build/linux-5.8/tools/bpf/bpftool 5.8.8.0 make[4]: Leaving directory /build/linux-5.8 + +Although we pass the "--no-print-directory" option, this is overridden +by the environment variable "MAKEFLAGS=w". Clear MAKEFLAGS for the +"make kernelversion" command. + +I have no explanation for the doubled ".8" in the version string, but +this seems to fix that as well. + +Signed-off-by: Ben Hutchings <benh@debian.org> +--- +--- a/tools/bpf/bpftool/Makefile ++++ b/tools/bpf/bpftool/Makefile +@@ -25,7 +25,7 @@ endif + + LIBBPF = $(LIBBPF_PATH)libbpf.a + +-BPFTOOL_VERSION ?= $(shell make -rR --no-print-directory -sC ../../.. kernelversion) ++BPFTOOL_VERSION ?= $(shell MAKEFLAGS= make -rR --no-print-directory -sC ../../.. kernelversion) + + $(LIBBPF): FORCE + $(if $(LIBBPF_OUTPUT),@mkdir -p $(LIBBPF_OUTPUT)) diff --git a/debian/patches/bugfix/all/cpupower-bump-soname-version.patch b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch new file mode 100644 index 000000000..7e5f52eaa --- /dev/null +++ b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch @@ -0,0 +1,27 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 9 Jun 2016 23:35:08 +0100 +Subject: cpupower: Bump soname version +Forwarded: http://mid.gmane.org/20160610005619.GQ7555@decadent.org.uk + +Several functions in the libcpupower API are renamed or removed in +Linux 4.7. This is an backward-incompatible ABI change, so the +library soname should change from libcpupower.so.0 to +libcpupower.so.1. + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/power/cpupower/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/power/cpupower/Makefile ++++ b/tools/power/cpupower/Makefile +@@ -53,7 +53,7 @@ DESTDIR ?= + + VERSION:= $(shell ./utils/version-gen.sh) + LIB_MAJ= 0.0.1 +-LIB_MIN= 0 ++LIB_MIN= 1 + + PACKAGE = cpupower + PACKAGE_BUGREPORT = linux-pm@vger.kernel.org diff --git a/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch new file mode 100644 index 000000000..5cce9b76a --- /dev/null +++ b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch @@ -0,0 +1,49 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 03 Nov 2016 15:25:26 -0600 +Subject: cpupower: Fix checks for CPU existence +Forwarded: https://marc.info/?l=linux-pm&m=149248268214265 + +Calls to cpufreq_cpu_exists(cpu) were converted to +cpupower_is_cpu_online(cpu) when libcpupower was introduced and the +former function was deleted. However, cpupower_is_cpu_online() does +not distinguish physically absent and offline CPUs, and does not set +errno. + +cpufreq-set has already been fixed (commit c25badc9ceb6). + +In cpufreq-bench, which prints an error message for offline CPUs, +properly distinguish and report the zero and negative cases. + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Fixes: 53d1cd6b125f ("cpupowerutils: bench - Fix cpu online check") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[carnil: Update/Refresh patch for 4.14.17: The issue with the +incorrect check has been fixed with upstream commit 53d1cd6b125f. +Keep in the patch the distinction and report for the zero and +negative cases.] +--- +--- a/tools/power/cpupower/bench/system.c ++++ b/tools/power/cpupower/bench/system.c +@@ -58,12 +58,19 @@ long long int get_time() + + int set_cpufreq_governor(char *governor, unsigned int cpu) + { ++ int rc; + + dprintf("set %s as cpufreq governor\n", governor); + +- if (cpupower_is_cpu_online(cpu) != 1) { +- perror("cpufreq_cpu_exists"); +- fprintf(stderr, "error: cpu %u does not exist\n", cpu); ++ rc = cpupower_is_cpu_online(cpu); ++ if (rc != 1) { ++ if (rc < 0) ++ fprintf(stderr, "cpupower_is_cpu_online: %s\n", ++ strerror(-rc)); ++ else ++ fprintf(stderr, ++ "error: cpu %u is offline or does not exist\n", ++ cpu); + return -1; + } + diff --git a/debian/patches/bugfix/all/disable-some-marvell-phys.patch b/debian/patches/bugfix/all/disable-some-marvell-phys.patch new file mode 100644 index 000000000..31fd6bf14 --- /dev/null +++ b/debian/patches/bugfix/all/disable-some-marvell-phys.patch @@ -0,0 +1,91 @@ +From: Ian Campbell <ijc@hellion.org.uk> +Subject: phy/marvell: disable 4-port phys +Date: Wed, 20 Nov 2013 08:30:14 +0000 +Bug-Debian: https://bugs.debian.org/723177 +Forwarded: http://thread.gmane.org/gmane.linux.debian.devel.bugs.general/1107774/ + +The Marvell PHY was originally disabled because it can cause networking +failures on some systems. According to Lennert Buytenhek this is because some +of the variants added did not share the same register layout. Since the known +cases are all 4-ports disable those variants (indicated by a 4 in the +penultimate position of the model name) until they can be audited for +correctness. + +[bwh: Also #if-out the init functions for these PHYs to avoid + compiler warnings] + +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -1006,6 +1006,7 @@ static int m88e1118_config_init(struct p + return genphy_soft_reset(phydev); + } + ++#if 0 + static int m88e1149_config_init(struct phy_device *phydev) + { + int err; +@@ -1031,7 +1032,9 @@ static int m88e1149_config_init(struct p + + return genphy_soft_reset(phydev); + } ++#endif + ++#if 0 + static int m88e1145_config_init_rgmii(struct phy_device *phydev) + { + int err; +@@ -1106,6 +1109,7 @@ static int m88e1145_config_init(struct p + + return 0; + } ++#endif + + static int m88e1540_get_fld(struct phy_device *phydev, u8 *msecs) + { +@@ -2272,6 +2276,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1145, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2293,6 +2298,8 @@ static struct phy_driver marvell_drivers + .get_tunable = m88e1111_get_tunable, + .set_tunable = m88e1111_set_tunable, + }, ++#endif ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1149R, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2311,6 +2318,8 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#endif ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1240, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2329,6 +2338,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#endif + { + .phy_id = MARVELL_PHY_ID_88E1116R, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2469,9 +2479,9 @@ static struct mdio_device_id __maybe_unu + { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, ++/* { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, */ ++/* { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, */ ++/* { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, */ + { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, diff --git a/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch new file mode 100644 index 000000000..8ee5acc89 --- /dev/null +++ b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch @@ -0,0 +1,2557 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: firmware: Remove redundant log messages from drivers +Date: Sun, 09 Dec 2012 16:40:31 +0000 +Forwarded: no + +Now that firmware_class logs every success and failure consistently, +many other log messages can be removed from drivers. + +This will probably need to be split up into multiple patches prior to +upstream submission. + +--- a/arch/x86/kernel/cpu/microcode/amd.c ++++ b/arch/x86/kernel/cpu/microcode/amd.c +@@ -901,10 +901,8 @@ static enum ucode_state request_microcod + if (c->x86 >= 0x15) + snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); + +- if (request_firmware_direct(&fw, (const char *)fw_name, device)) { +- pr_debug("failed to load file %s\n", fw_name); ++ if (request_firmware_direct(&fw, (const char *)fw_name, device)) + goto out; +- } + + ret = UCODE_ERROR; + if (!verify_container(fw->data, fw->size, false)) +--- a/drivers/atm/ambassador.c ++++ b/drivers/atm/ambassador.c +@@ -1914,10 +1914,8 @@ static int ucode_init(loader_block *lb, + int res; + + res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); +- if (res) { +- PRINTK (KERN_ERR, "Cannot load microcode data"); ++ if (res) + return res; +- } + + /* First record contains just the start address */ + rec = (const struct ihex_binrec *)fw->data; +--- a/drivers/atm/fore200e.c ++++ b/drivers/atm/fore200e.c +@@ -2400,10 +2400,9 @@ static int fore200e_load_and_start_fw(st + int err; + + sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); +- if ((err = request_firmware(&firmware, buf, fore200e->dev)) < 0) { +- printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name); ++ err = request_firmware(&firmware, buf, fore200e->dev); ++ if (err) + return err; +- } + + fw_data = (const __le32 *)firmware->data; + fw_size = firmware->size / sizeof(u32); +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -382,10 +382,8 @@ static int ath3k_load_patch(struct usb_d + le32_to_cpu(fw_version.rom_version)); + + ret = request_firmware(&firmware, filename, &udev->dev); +- if (ret < 0) { +- BT_ERR("Patch file not found %s", filename); ++ if (ret) + return ret; +- } + + pt_rom_version = get_unaligned_le32(firmware->data + + firmware->size - 8); +@@ -445,10 +443,8 @@ static int ath3k_load_syscfg(struct usb_ + le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + + ret = request_firmware(&firmware, filename, &udev->dev); +- if (ret < 0) { +- BT_ERR("Configuration file not found %s", filename); ++ if (ret) + return ret; +- } + + ret = ath3k_load_fwfile(udev, firmware); + release_firmware(firmware); +--- a/drivers/bluetooth/bcm203x.c ++++ b/drivers/bluetooth/bcm203x.c +@@ -174,7 +174,6 @@ static int bcm203x_probe(struct usb_inte + return -ENOMEM; + + if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { +- BT_ERR("Mini driver request failed"); + usb_free_urb(data->urb); + return -EIO; + } +@@ -199,7 +198,6 @@ static int bcm203x_probe(struct usb_inte + release_firmware(firmware); + + if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { +- BT_ERR("Firmware request failed"); + usb_free_urb(data->urb); + kfree(data->buffer); + return -EIO; +--- a/drivers/bluetooth/bfusb.c ++++ b/drivers/bluetooth/bfusb.c +@@ -636,10 +636,8 @@ static int bfusb_probe(struct usb_interf + skb_queue_head_init(&data->pending_q); + skb_queue_head_init(&data->completed_q); + +- if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { +- BT_ERR("Firmware request failed"); ++ if (request_firmware(&firmware, "bfubase.frm", &udev->dev)) + goto done; +- } + + BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); + +--- a/drivers/bluetooth/bt3c_cs.c ++++ b/drivers/bluetooth/bt3c_cs.c +@@ -569,10 +569,8 @@ static int bt3c_open(struct bt3c_info *i + + /* Load firmware */ + err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); +- if (err < 0) { +- BT_ERR("Firmware request failed"); ++ if (err) + goto error; +- } + + err = bt3c_load_firmware(info, firmware->data, firmware->size); + +--- a/drivers/bluetooth/btmrvl_sdio.c ++++ b/drivers/bluetooth/btmrvl_sdio.c +@@ -483,8 +483,6 @@ static int btmrvl_sdio_download_helper(s + ret = request_firmware(&fw_helper, card->helper, + &card->func->dev); + if ((ret < 0) || !fw_helper) { +- BT_ERR("request_firmware(helper) failed, error code = %d", +- ret); + ret = -ENOENT; + goto done; + } +@@ -583,8 +581,6 @@ static int btmrvl_sdio_download_fw_w_hel + ret = request_firmware(&fw_firmware, card->firmware, + &card->func->dev); + if ((ret < 0) || !fw_firmware) { +- BT_ERR("request_firmware(firmware) failed, error code = %d", +- ret); + ret = -ENOENT; + goto done; + } +--- a/drivers/char/dsp56k.c ++++ b/drivers/char/dsp56k.c +@@ -140,11 +140,8 @@ static int dsp56k_upload(u_char __user * + } + err = request_firmware(&fw, fw_name, &pdev->dev); + platform_device_unregister(pdev); +- if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fw_name, err); ++ if (err) + return err; +- } + if (fw->size % 3) { + printk(KERN_ERR "Bogus length %d in image \"%s\"\n", + fw->size, fw_name); +--- a/drivers/dma/imx-sdma.c ++++ b/drivers/dma/imx-sdma.c +@@ -1733,11 +1733,8 @@ static void sdma_load_firmware(const str + const struct sdma_script_start_addrs *addr; + unsigned short *ram_code; + +- if (!fw) { +- dev_info(sdma->dev, "external firmware not found, using ROM firmware\n"); +- /* In this case we just use the ROM firmware. */ ++ if (!fw) + return; +- } + + if (fw->size < sizeof(*header)) + goto err_firmware; +--- a/drivers/gpu/drm/mga/mga_warp.c ++++ b/drivers/gpu/drm/mga/mga_warp.c +@@ -77,11 +77,8 @@ int mga_warp_install_microcode(drm_mga_p + } + rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); + platform_device_unregister(pdev); +- if (rc) { +- DRM_ERROR("mga: Failed to load microcode \"%s\"\n", +- firmware_name); ++ if (rc) + return rc; +- } + + size = 0; + where = 0; +--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +@@ -2445,10 +2445,8 @@ gf100_gr_load_fw(struct gf100_gr *gr, co + if (ret) { + snprintf(f, sizeof(f), "nouveau/%s", name); + ret = request_firmware(&fw, f, device->dev); +- if (ret) { +- nvkm_error(subdev, "failed to load %s\n", name); ++ if (ret) + return ret; +- } + } + + blob->size = fw->size; +--- a/drivers/gpu/drm/r128/r128_cce.c ++++ b/drivers/gpu/drm/r128/r128_cce.c +@@ -162,11 +162,8 @@ static int r128_cce_load_microcode(drm_r + } + rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); + platform_device_unregister(pdev); +- if (rc) { +- pr_err("r128_cce: Failed to load firmware \"%s\"\n", +- FIRMWARE_NAME); ++ if (rc) + return rc; +- } + + if (fw->size != 256 * 8) { + pr_err("r128_cce: Bogus length %zu in firmware \"%s\"\n", +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -833,9 +833,6 @@ int ni_init_microcode(struct radeon_devi + + out: + if (err) { +- if (err != -EINVAL) +- pr_err("ni_cp: Failed to load firmware \"%s\"\n", +- fw_name); + release_firmware(rdev->pfp_fw); + rdev->pfp_fw = NULL; + release_firmware(rdev->me_fw); +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -1047,9 +1047,7 @@ static int r100_cp_init_microcode(struct + } + + err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); +- if (err) { +- pr_err("radeon_cp: Failed to load firmware \"%s\"\n", fw_name); +- } else if (rdev->me_fw->size % 8) { ++ if (err == 0 && rdev->me_fw->size % 8) { + pr_err("radeon_cp: Bogus length %zu in firmware \"%s\"\n", + rdev->me_fw->size, fw_name); + err = -EINVAL; +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2599,9 +2599,6 @@ int r600_init_microcode(struct radeon_de + + out: + if (err) { +- if (err != -EINVAL) +- pr_err("r600_cp: Failed to load firmware \"%s\"\n", +- fw_name); + release_firmware(rdev->pfp_fw); + rdev->pfp_fw = NULL; + release_firmware(rdev->me_fw); +--- a/drivers/infiniband/hw/qib/qib_sd7220.c ++++ b/drivers/infiniband/hw/qib/qib_sd7220.c +@@ -406,10 +406,8 @@ int qib_sd7220_init(struct qib_devdata * + } + + ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev); +- if (ret) { +- qib_dev_err(dd, "Failed to load IB SERDES image\n"); ++ if (ret) + goto done; +- } + + /* Substitute our deduced value for was_reset */ + ret = qib_ibsd_ucode_loaded(dd->pport, fw); +--- a/drivers/input/touchscreen/atmel_mxt_ts.c ++++ b/drivers/input/touchscreen/atmel_mxt_ts.c +@@ -2827,10 +2827,8 @@ static int mxt_load_fw(struct device *de + int ret; + + ret = request_firmware(&fw, fn, dev); +- if (ret) { +- dev_err(dev, "Unable to open firmware %s\n", fn); ++ if (ret) + return ret; +- } + + /* Check for incorrect enc file */ + ret = mxt_check_firmware_format(dev, fw); +--- a/drivers/isdn/hardware/mISDN/speedfax.c ++++ b/drivers/isdn/hardware/mISDN/speedfax.c +@@ -379,11 +379,8 @@ setup_instance(struct sfax_hw *card) + card->isar.owner = THIS_MODULE; + + err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev); +- if (err < 0) { +- pr_info("%s: firmware request failed %d\n", +- card->name, err); ++ if (err) + goto error_fw; +- } + if (debug & DEBUG_HW) + pr_notice("%s: got firmware %zu bytes\n", + card->name, firmware->size); +--- a/drivers/media/common/siano/smscoreapi.c ++++ b/drivers/media/common/siano/smscoreapi.c +@@ -1156,10 +1156,8 @@ static int smscore_load_firmware_from_fi + return -EINVAL; + + rc = request_firmware(&fw, fw_filename, coredev->device); +- if (rc < 0) { +- pr_err("failed to open firmware file '%s'\n", fw_filename); ++ if (rc < 0) + return rc; +- } + pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size); + fw_buf = kmalloc(ALIGN(fw->size + sizeof(struct sms_firmware), + SMS_ALLOC_ALIGNMENT), GFP_KERNEL | coredev->gfp_buf_flags); +--- a/drivers/media/dvb-frontends/af9013.c ++++ b/drivers/media/dvb-frontends/af9013.c +@@ -1049,14 +1049,8 @@ static int af9013_download_firmware(stru + + /* Request the firmware, will block and timeout */ + ret = request_firmware(&firmware, name, &client->dev); +- if (ret) { +- dev_info(&client->dev, "firmware file '%s' not found %d\n", +- name, ret); ++ if (ret) + goto err; +- } +- +- dev_info(&client->dev, "downloading firmware from file '%s'\n", +- name); + + /* Write firmware checksum & size */ + for (i = 0; i < firmware->size; i++) +--- a/drivers/media/dvb-frontends/bcm3510.c ++++ b/drivers/media/dvb-frontends/bcm3510.c +@@ -636,10 +636,9 @@ static int bcm3510_download_firmware(str + int ret,i; + + deb_info("requesting firmware\n"); +- if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) { +- err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); ++ ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE); ++ if (ret) + return ret; +- } + deb_info("got firmware: %zu\n", fw->size); + + b = fw->data; +--- a/drivers/media/dvb-frontends/cx24116.c ++++ b/drivers/media/dvb-frontends/cx24116.c +@@ -479,13 +479,8 @@ static int cx24116_firmware_ondemand(str + __func__, CX24116_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", +- __func__); +- if (ret) { +- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + /* Make sure we don't recurse back through here + * during loading */ +--- a/drivers/media/dvb-frontends/drxd_hard.c ++++ b/drivers/media/dvb-frontends/drxd_hard.c +@@ -891,10 +891,8 @@ static int load_firmware(struct drxd_sta + { + const struct firmware *fw; + +- if (request_firmware(&fw, fw_name, state->dev) < 0) { +- printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name); ++ if (request_firmware(&fw, fw_name, state->dev)) + return -EIO; +- } + + state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); + if (!state->microcode) { +--- a/drivers/media/dvb-frontends/drxk_hard.c ++++ b/drivers/media/dvb-frontends/drxk_hard.c +@@ -6259,10 +6259,6 @@ static void load_firmware_cb(const struc + + dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); + if (!fw) { +- pr_err("Could not load firmware file %s.\n", +- state->microcode_name); +- pr_info("Copy %s to your hotplug directory!\n", +- state->microcode_name); + state->microcode_name = NULL; + + /* +--- a/drivers/media/dvb-frontends/ds3000.c ++++ b/drivers/media/dvb-frontends/ds3000.c +@@ -348,12 +348,8 @@ static int ds3000_firmware_ondemand(stru + DS3000_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = ds3000_load_firmware(fe, fw); + if (ret) +--- a/drivers/media/dvb-frontends/nxt200x.c ++++ b/drivers/media/dvb-frontends/nxt200x.c +@@ -876,12 +876,8 @@ static int nxt2002_init(struct dvb_front + __func__, NXT2002_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- pr_err("%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = nxt2002_load_firmware(fe, fw); + release_firmware(fw); +@@ -943,12 +939,8 @@ static int nxt2004_init(struct dvb_front + __func__, NXT2004_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- pr_err("%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = nxt2004_load_firmware(fe, fw); + release_firmware(fw); +--- a/drivers/media/dvb-frontends/or51132.c ++++ b/drivers/media/dvb-frontends/or51132.c +@@ -326,10 +326,8 @@ static int or51132_set_parameters(struct + printk("or51132: Waiting for firmware upload(%s)...\n", + fwname); + ret = request_firmware(&fw, fwname, state->i2c->dev.parent); +- if (ret) { +- printk(KERN_WARNING "or51132: No firmware uploaded(timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + ret = or51132_load_firmware(fe, fw); + release_firmware(fw); + if (ret) { +--- a/drivers/media/dvb-frontends/or51211.c ++++ b/drivers/media/dvb-frontends/or51211.c +@@ -361,11 +361,8 @@ static int or51211_init(struct dvb_front + OR51211_DEFAULT_FIRMWARE); + ret = config->request_firmware(fe, &fw, + OR51211_DEFAULT_FIRMWARE); +- pr_info("Got Hotplug firmware\n"); +- if (ret) { +- pr_warn("No firmware uploaded (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + ret = or51211_load_firmware(fe, fw); + release_firmware(fw); +--- a/drivers/media/dvb-frontends/sp8870.c ++++ b/drivers/media/dvb-frontends/sp8870.c +@@ -304,10 +304,8 @@ static int sp8870_init (struct dvb_front + + /* request the firmware, this will block until someone uploads it */ + 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"); ++ if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) + return -EIO; +- } + + if (sp8870_firmware_upload(state, fw)) { + printk("sp8870: writing firmware to device failed\n"); +--- a/drivers/media/dvb-frontends/sp887x.c ++++ b/drivers/media/dvb-frontends/sp887x.c +@@ -527,10 +527,8 @@ static int sp887x_init(struct dvb_fronte + /* request the firmware, this will block until someone uploads it */ + printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE); + ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE); +- if (ret) { +- printk("sp887x: no firmware upload (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + ret = sp887x_initial_setup(fe, fw); + release_firmware(fw); +--- a/drivers/media/dvb-frontends/tda10048.c ++++ b/drivers/media/dvb-frontends/tda10048.c +@@ -483,8 +483,6 @@ static int tda10048_firmware_upload(stru + ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, + state->i2c->dev.parent); + if (ret) { +- printk(KERN_ERR "%s: Upload failed. (file not found?)\n", +- __func__); + return -EIO; + } else { + printk(KERN_INFO "%s: firmware read %zu bytes.\n", +--- a/drivers/media/dvb-frontends/tda1004x.c ++++ b/drivers/media/dvb-frontends/tda1004x.c +@@ -388,10 +388,8 @@ static int tda10045_fwupload(struct dvb_ + /* request the firmware, this will block until someone uploads it */ + printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); + ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); +- if (ret) { +- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + /* reset chip */ + tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); +@@ -532,7 +530,6 @@ static int tda10046_fwupload(struct dvb_ + /* remain compatible to old bug: try to load with tda10045 image name */ + ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); + if (ret) { +- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); + return ret; + } else { + printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", +--- a/drivers/media/dvb-frontends/tda10071.c ++++ b/drivers/media/dvb-frontends/tda10071.c +@@ -838,12 +838,8 @@ static int tda10071_init(struct dvb_fron + + /* request the firmware, this will block and timeout */ + ret = request_firmware(&fw, fw_file, &client->dev); +- if (ret) { +- dev_err(&client->dev, +- "did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware\n", +- fw_file, ret); ++ if (ret) + goto error; +- } + + /* init */ + for (i = 0; i < ARRAY_SIZE(tab2); i++) { +--- a/drivers/media/i2c/cx25840/cx25840-firmware.c ++++ b/drivers/media/i2c/cx25840/cx25840-firmware.c +@@ -113,10 +113,8 @@ int cx25840_loadfw(struct i2c_client *cl + if (is_cx231xx(state) && max_buf_size > 16) + max_buf_size = 16; + +- if (request_firmware(&fw, fwname, FWDEV(client)) != 0) { +- v4l_err(client, "unable to open firmware %s\n", fwname); ++ if (request_firmware(&fw, fwname, FWDEV(client)) != 0) + return -EINVAL; +- } + + start_fw_load(client); + +--- a/drivers/media/pci/bt8xx/bttv-cards.c ++++ b/drivers/media/pci/bt8xx/bttv-cards.c +@@ -3904,10 +3904,8 @@ static int pvr_boot(struct bttv *btv) + int rc; + + rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); +- if (rc != 0) { +- pr_warn("%d: no altera firmware [via hotplug]\n", btv->c.nr); ++ if (rc != 0) + return rc; +- } + rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); + pr_info("%d: altera firmware upload %s\n", + btv->c.nr, (rc < 0) ? "failed" : "ok"); +--- a/drivers/media/pci/cx18/cx18-av-firmware.c ++++ b/drivers/media/pci/cx18/cx18-av-firmware.c +@@ -70,10 +70,8 @@ int cx18_av_loadfw(struct cx18 *cx) + int i; + int retries1 = 0; + +- if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) { +- CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE); ++ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) + return -EINVAL; +- } + + /* The firmware load often has byte errors, so allow for several + retries, both at byte level and at the firmware load level. */ +--- a/drivers/media/pci/cx18/cx18-dvb.c ++++ b/drivers/media/pci/cx18/cx18-dvb.c +@@ -127,9 +127,7 @@ static int yuan_mpc718_mt352_reqfw(struc + int ret; + + ret = request_firmware(fw, fn, &cx->pci_dev->dev); +- if (ret) +- CX18_ERR("Unable to open firmware file %s\n", fn); +- else { ++ if (!ret) { + size_t sz = (*fw)->size; + if (sz < 2 || sz > 64 || (sz % 2) != 0) { + CX18_ERR("Firmware %s has a bad size: %lu bytes\n", +--- a/drivers/media/pci/cx18/cx18-firmware.c ++++ b/drivers/media/pci/cx18/cx18-firmware.c +@@ -92,11 +92,8 @@ static int load_cpu_fw_direct(const char + u32 __iomem *dst = (u32 __iomem *)mem; + const u32 *src; + +- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { +- CX18_ERR("Unable to open firmware %s\n", fn); +- CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); ++ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) + return -ENOMEM; +- } + + src = (const u32 *)fw->data; + +@@ -137,8 +134,6 @@ static int load_apu_fw_direct(const char + int sz; + + if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { +- CX18_ERR("unable to open firmware %s\n", fn); +- CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); + cx18_setup_page(cx, 0); + return -ENOMEM; + } +--- a/drivers/media/pci/cx23885/cx23885-417.c ++++ b/drivers/media/pci/cx23885/cx23885-417.c +@@ -920,12 +920,8 @@ static int cx23885_load_firmware(struct + retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, + &dev->pci->dev); + +- if (retval != 0) { +- pr_err("ERROR: Hotplug firmware request failed (%s).\n", +- CX23885_FIRM_IMAGE_NAME); +- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); ++ if (retval != 0) + return -1; +- } + + if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { + pr_err("ERROR: Firmware size mismatch (have %zu, expected %d)\n", +--- a/drivers/media/pci/cx23885/cx23885-cards.c ++++ b/drivers/media/pci/cx23885/cx23885-cards.c +@@ -2480,10 +2480,7 @@ void cx23885_card_setup(struct cx23885_d + cinfo.rev, filename); + + ret = request_firmware(&fw, filename, &dev->pci->dev); +- if (ret != 0) +- pr_err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware.", +- filename); +- else ++ if (ret == 0) + altera_init(&netup_config, fw); + + release_firmware(fw); +--- a/drivers/media/pci/cx88/cx88-blackbird.c ++++ b/drivers/media/pci/cx88/cx88-blackbird.c +@@ -462,12 +462,8 @@ static int blackbird_load_firmware(struc + retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, + &dev->pci->dev); + +- if (retval != 0) { +- pr_err("Hotplug firmware request failed (%s).\n", +- CX2341X_FIRM_ENC_FILENAME); +- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); ++ if (retval != 0) + return -EIO; +- } + + if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { + pr_err("Firmware size mismatch (have %zd, expected %d)\n", +--- a/drivers/media/pci/ivtv/ivtv-firmware.c ++++ b/drivers/media/pci/ivtv/ivtv-firmware.c +@@ -68,8 +68,6 @@ retry: + release_firmware(fw); + return size; + } +- IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); +- IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n"); + return -ENOMEM; + } + +--- a/drivers/media/pci/ngene/ngene-core.c ++++ b/drivers/media/pci/ngene/ngene-core.c +@@ -1236,19 +1236,14 @@ static int ngene_load_firm(struct ngene + break; + } + +- if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { +- dev_err(pdev, "Could not load firmware file %s.\n", fw_name); +- dev_info(pdev, "Copy %s to your hotplug directory!\n", +- fw_name); ++ if (request_firmware(&fw, fw_name, &dev->pci_dev->dev)) + return -1; +- } + if (size == 0) + size = fw->size; + if (size != fw->size) { + dev_err(pdev, "Firmware %s has invalid size!", fw_name); + err = -1; + } else { +- dev_info(pdev, "Loading firmware file %s.\n", fw_name); + ngene_fw = (u8 *) fw->data; + err = ngene_command_load_firmware(dev, ngene_fw, size); + } +--- a/drivers/media/pci/saa7164/saa7164-fw.c ++++ b/drivers/media/pci/saa7164/saa7164-fw.c +@@ -406,11 +406,8 @@ int saa7164_downloadfirmware(struct saa7 + __func__, fwname); + + ret = request_firmware(&fw, fwname, &dev->pci->dev); +- if (ret) { +- printk(KERN_ERR "%s() Upload failed. (file not found?)\n", +- __func__); ++ if (ret) + return -ENOMEM; +- } + + printk(KERN_INFO "%s() firmware read %zu bytes.\n", + __func__, fw->size); +--- a/drivers/media/pci/ttpci/av7110.c ++++ b/drivers/media/pci/ttpci/av7110.c +@@ -1501,13 +1501,8 @@ static int get_firmware(struct av7110* a + /* request the av7110 firmware, this will block until someone uploads it */ + ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); + if (ret) { +- if (ret == -ENOENT) { +- printk(KERN_ERR "dvb-ttpci: could not load firmware, file not found: dvb-ttpci-01.fw\n"); +- printk(KERN_ERR "dvb-ttpci: usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n"); +- printk(KERN_ERR "dvb-ttpci: and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n"); +- } else +- printk(KERN_ERR "dvb-ttpci: cannot request firmware (error %i)\n", +- ret); ++ if (ret == -ENOENT) ++ printk(KERN_ERR "dvb-ttpci: firmware can be downloaded from https://linuxtv.org/download/dvb/firmware/\n"); + return -EINVAL; + } + +--- a/drivers/media/pci/ttpci/av7110_hw.c ++++ b/drivers/media/pci/ttpci/av7110_hw.c +@@ -235,11 +235,8 @@ int av7110_bootarm(struct av7110 *av7110 + //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); + + ret = request_firmware(&fw, fw_name, &dev->pci->dev); +- if (ret) { +- printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n", +- fw_name); ++ if (ret) + return ret; +- } + + mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); + release_firmware(fw); +--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c ++++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +@@ -65,10 +65,8 @@ int s5p_mfc_load_firmware(struct s5p_mfc + } + } + +- if (err != 0) { +- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); ++ if (err != 0) + return -EINVAL; +- } + if (fw_blob->size > dev->fw_buf.size) { + mfc_err("MFC firmware is too big to be loaded\n"); + release_firmware(fw_blob); +--- a/drivers/media/radio/radio-wl1273.c ++++ b/drivers/media/radio/radio-wl1273.c +@@ -502,11 +502,8 @@ static int wl1273_fm_upload_firmware_pat + * Uploading the firmware patch is not always necessary, + * so we only print an info message. + */ +- if (request_firmware(&fw_p, fw_name, dev)) { +- dev_info(dev, "%s - %s not found\n", __func__, fw_name); +- ++ if (request_firmware(&fw_p, fw_name, dev)) + return 0; +- } + + ptr = (__u8 *) fw_p->data; + packet_num = ptr[0]; +--- a/drivers/media/radio/wl128x/fmdrv_common.c ++++ b/drivers/media/radio/wl128x/fmdrv_common.c +@@ -1240,10 +1240,8 @@ static int fm_download_firmware(struct f + + ret = request_firmware(&fw_entry, fw_name, + &fmdev->radio_dev->dev); +- if (ret < 0) { +- fmerr("Unable to read firmware(%s) content\n", fw_name); ++ if (ret) + return ret; +- } + fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size); + + fw_data = (void *)fw_entry->data; +--- a/drivers/media/tuners/tuner-xc2028.c ++++ b/drivers/media/tuners/tuner-xc2028.c +@@ -1366,7 +1366,6 @@ static void load_firmware_cb(const struc + + tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); + if (!fw) { +- tuner_err("Could not load firmware %s.\n", priv->fname); + priv->state = XC2028_NODEV; + return; + } +--- a/drivers/media/usb/cpia2/cpia2_core.c ++++ b/drivers/media/usb/cpia2/cpia2_core.c +@@ -912,11 +912,8 @@ static int apply_vp_patch(struct camera_ + struct cpia2_command cmd; + + ret = request_firmware(&fw, fw_name, &cam->dev->dev); +- if (ret) { +- printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n", +- fw_name); ++ if (ret) + return ret; +- } + + cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; + cmd.direction = TRANSFER_WRITE; +--- a/drivers/media/usb/cx231xx/cx231xx-417.c ++++ b/drivers/media/usb/cx231xx/cx231xx-417.c +@@ -983,11 +983,6 @@ static int cx231xx_load_firmware(struct + dev->dev); + + if (retval != 0) { +- dev_err(dev->dev, +- "ERROR: Hotplug firmware request failed (%s).\n", +- CX231xx_FIRM_IMAGE_NAME); +- dev_err(dev->dev, +- "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + vfree(p_current_fw); + vfree(p_buffer); + return retval; +--- a/drivers/media/usb/dvb-usb/dib0700_devices.c ++++ b/drivers/media/usb/dvb-usb/dib0700_devices.c +@@ -2408,12 +2408,9 @@ static int stk9090m_frontend_attach(stru + + dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); + +- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { +- deb_info("%s: Upload failed. (file not found?)\n", __func__); ++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) + return -ENODEV; +- } else { +- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); +- } ++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); + stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; + stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; + +@@ -2478,12 +2475,9 @@ static int nim9090md_frontend_attach(str + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + +- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { +- deb_info("%s: Upload failed. (file not found?)\n", __func__); ++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) + return -EIO; +- } else { +- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); +- } ++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); + nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; + nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; + nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size; +--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c ++++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +@@ -90,13 +90,9 @@ int dvb_usb_download_firmware(struct usb + int ret; + const struct firmware *fw = NULL; + +- if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { +- err("did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- props->firmware,ret); ++ ret = request_firmware(&fw, props->firmware, &udev->dev); ++ if (ret) + return ret; +- } +- +- info("downloading firmware from file '%s'",props->firmware); + + switch (props->usb_ctrl) { + case CYPRESS_AN2135: +--- a/drivers/media/usb/dvb-usb/gp8psk.c ++++ b/drivers/media/usb/dvb-usb/gp8psk.c +@@ -131,19 +131,14 @@ static int gp8psk_load_bcm4500fw(struct + const u8 *ptr; + u8 *buf; + if ((ret = request_firmware(&fw, bcm4500_firmware, +- &d->udev->dev)) != 0) { +- err("did not find the bcm4500 firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- bcm4500_firmware,ret); ++ &d->udev->dev)) != 0) + return ret; +- } + + ret = -EINVAL; + + if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) + goto out_rel_fw; + +- info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware); +- + ptr = fw->data; + buf = kmalloc(64, GFP_KERNEL); + if (!buf) { +--- a/drivers/media/usb/dvb-usb/opera1.c ++++ b/drivers/media/usb/dvb-usb/opera1.c +@@ -450,8 +450,6 @@ static int opera1_xilinx_load_firmware(s + info("start downloading fpga firmware %s",filename); + + if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { +- err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- filename); + return ret; + } else { + p = kmalloc(fw->size, GFP_KERNEL); +--- a/drivers/media/usb/go7007/go7007-driver.c ++++ b/drivers/media/usb/go7007/go7007-driver.c +@@ -84,10 +84,8 @@ static int go7007_load_encoder(struct go + u16 intr_val, intr_data; + + if (go->boot_fw == NULL) { +- if (request_firmware(&fw_entry, fw_name, go->dev)) { +- v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name); ++ if (request_firmware(&fw_entry, fw_name, go->dev)) + return -1; +- } + if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { + v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name); + release_firmware(fw_entry); +--- a/drivers/media/usb/go7007/go7007-fw.c ++++ b/drivers/media/usb/go7007/go7007-fw.c +@@ -1565,12 +1565,8 @@ int go7007_construct_fw_image(struct go7 + default: + return -1; + } +- if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) { +- dev_err(go->dev, +- "unable to load firmware from file \"%s\"\n", +- GO7007_FW_NAME); ++ if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) + return -1; +- } + code = kcalloc(codespace, 2, GFP_KERNEL); + if (code == NULL) + goto fw_failed; +--- a/drivers/media/usb/go7007/go7007-loader.c ++++ b/drivers/media/usb/go7007/go7007-loader.c +@@ -67,11 +67,8 @@ static int go7007_loader_probe(struct us + + dev_info(&interface->dev, "loading firmware %s\n", fw1); + +- if (request_firmware(&fw, fw1, &usbdev->dev)) { +- dev_err(&interface->dev, +- "unable to load firmware from file \"%s\"\n", fw1); ++ if (request_firmware(&fw, fw1, &usbdev->dev)) + goto failed2; +- } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { +@@ -82,11 +79,8 @@ static int go7007_loader_probe(struct us + if (fw2 == NULL) + return 0; + +- if (request_firmware(&fw, fw2, &usbdev->dev)) { +- dev_err(&interface->dev, +- "unable to load firmware from file \"%s\"\n", fw2); ++ if (request_firmware(&fw, fw2, &usbdev->dev)) + goto failed2; +- } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { +--- a/drivers/media/usb/gspca/vicam.c ++++ b/drivers/media/usb/gspca/vicam.c +@@ -230,10 +230,8 @@ static int sd_init(struct gspca_dev *gsp + + ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, + &gspca_dev->dev->dev); +- if (ret) { +- pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret); ++ if (ret) + return ret; +- } + + firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!firmware_buf) { +--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +@@ -1370,25 +1370,6 @@ static int pvr2_locate_firmware(struct p + "request_firmware fatal error with code=%d",ret); + return ret; + } +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "***WARNING*** Device %s firmware seems to be missing.", +- fwtypename); +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "Did you install the pvrusb2 firmware files in their proper location?"); +- if (fwcount == 1) { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware unable to locate %s file %s", +- fwtypename,fwnames[0]); +- } else { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware unable to locate one of the following %s files:", +- fwtypename); +- for (idx = 0; idx < fwcount; idx++) { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware: Failed to find %s", +- fwnames[idx]); +- } +- } + return ret; + } + +--- a/drivers/media/usb/s2255/s2255drv.c ++++ b/drivers/media/usb/s2255/s2255drv.c +@@ -2278,10 +2278,8 @@ static int s2255_probe(struct usb_interf + } + /* load the first chunk */ + if (request_firmware(&dev->fw_data->fw, +- FIRMWARE_FILE_NAME, &dev->udev->dev)) { +- dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n"); ++ FIRMWARE_FILE_NAME, &dev->udev->dev)) + goto errorREQFW; +- } + /* check the firmware is valid */ + fw_size = dev->fw_data->fw->size; + pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; +--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c ++++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +@@ -282,10 +282,8 @@ static int ttusb_boot_dsp(struct ttusb * + + err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin", + &ttusb->dev->dev); +- if (err) { +- pr_err("failed to request firmware\n"); ++ if (err) + return err; +- } + + /* BootBlock */ + b[0] = 0xaa; +--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c ++++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c +@@ -1324,11 +1324,8 @@ static int ttusb_dec_boot_dsp(struct ttu + dprintk("%s\n", __func__); + + result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev); +- if (result) { +- printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", +- __func__, dec->firmware_name); ++ if (result) + return result; +- } + + firmware = fw_entry->data; + firmware_size = fw_entry->size; +--- a/drivers/misc/ti-st/st_kim.c ++++ b/drivers/misc/ti-st/st_kim.c +@@ -295,11 +295,8 @@ static long download_firmware(struct kim + request_firmware(&kim_gdata->fw_entry, bts_scr_name, + &kim_gdata->kim_pdev->dev); + if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) || +- (kim_gdata->fw_entry->size == 0))) { +- pr_err(" request_firmware failed(errno %ld) for %s", err, +- bts_scr_name); ++ (kim_gdata->fw_entry->size == 0))) + return -EINVAL; +- } + ptr = (void *)kim_gdata->fw_entry->data; + len = kim_gdata->fw_entry->size; + /* +--- a/drivers/net/can/softing/softing_fw.c ++++ b/drivers/net/can/softing/softing_fw.c +@@ -226,11 +226,8 @@ int softing_load_app_fw(const char *file + int8_t type_end = 0, type_entrypoint = 0; + + ret = request_firmware(&fw, file, &card->pdev->dev); +- if (ret) { +- dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", +- file, ret); ++ if (ret) + return ret; +- } + dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", + file, (unsigned long)fw->size); + /* parse the firmware */ +--- a/drivers/net/ethernet/3com/typhoon.c ++++ b/drivers/net/ethernet/3com/typhoon.c +@@ -1282,11 +1282,8 @@ typhoon_request_firmware(struct typhoon + return 0; + + err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); +- if (err) { +- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", +- FIRMWARE_NAME); ++ if (err) + return err; +- } + + image_data = typhoon_fw->data; + remaining = typhoon_fw->size; +--- a/drivers/net/ethernet/adaptec/starfire.c ++++ b/drivers/net/ethernet/adaptec/starfire.c +@@ -1002,11 +1002,8 @@ static int netdev_open(struct net_device + #endif /* VLAN_SUPPORT */ + + retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev); +- if (retval) { +- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", +- FIRMWARE_RX); ++ if (retval) + goto out_init; +- } + if (fw_rx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_rx->size, FIRMWARE_RX); +@@ -1014,11 +1011,8 @@ static int netdev_open(struct net_device + goto out_rx; + } + retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev); +- if (retval) { +- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", +- FIRMWARE_TX); ++ if (retval) + goto out_rx; +- } + if (fw_tx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_tx->size, FIRMWARE_TX); +--- a/drivers/net/ethernet/alacritech/slicoss.c ++++ b/drivers/net/ethernet/alacritech/slicoss.c +@@ -1051,11 +1051,8 @@ static int slic_load_rcvseq_firmware(str + file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_RCV_FIRMWARE_OASIS : + SLIC_RCV_FIRMWARE_MOJAVE; + err = request_firmware(&fw, file, &sdev->pdev->dev); +- if (err) { +- dev_err(&sdev->pdev->dev, +- "failed to load receive sequencer firmware %s\n", file); ++ if (err) + return err; +- } + /* Do an initial sanity check concerning firmware size now. A further + * check follows below. + */ +@@ -1126,10 +1123,8 @@ static int slic_load_firmware(struct sli + file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_FIRMWARE_OASIS : + SLIC_FIRMWARE_MOJAVE; + err = request_firmware(&fw, file, &sdev->pdev->dev); +- if (err) { +- dev_err(&sdev->pdev->dev, "failed to load firmware %s\n", file); ++ if (err) + return err; +- } + /* Do an initial sanity check concerning firmware size now. A further + * check follows below. + */ +--- a/drivers/net/ethernet/alteon/acenic.c ++++ b/drivers/net/ethernet/alteon/acenic.c +@@ -2881,11 +2881,8 @@ static int ace_load_firmware(struct net_ + fw_name = "acenic/tg1.bin"; + + ret = request_firmware(&fw, fw_name, &ap->pdev->dev); +- if (ret) { +- printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", +- ap->name, fw_name); ++ if (ret) + return ret; +- } + + fw_data = (void *)fw->data; + +--- a/drivers/net/ethernet/broadcom/bnx2.c ++++ b/drivers/net/ethernet/broadcom/bnx2.c +@@ -3712,16 +3712,13 @@ static int bnx2_request_uncached_firmwar + } + + rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev); +- if (rc) { +- pr_err("Can't load firmware file \"%s\"\n", mips_fw_file); ++ if (rc) + goto out; +- } + + rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev); +- if (rc) { +- pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file); ++ if (rc) + goto err_release_mips_firmware; +- } ++ + mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data; + rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data; + if (bp->mips_firmware->size < sizeof(*mips_fw) || +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -11413,11 +11413,8 @@ static int tg3_request_firmware(struct t + { + const struct tg3_firmware_hdr *fw_hdr; + +- if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { +- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", +- tp->fw_needed); ++ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) + return -ENOENT; +- } + + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; + +--- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c ++++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c +@@ -24,10 +24,8 @@ cna_read_firmware(struct pci_dev *pdev, + const struct firmware *fw; + u32 n; + +- if (request_firmware(&fw, fw_name, &pdev->dev)) { +- dev_alert(&pdev->dev, "can't load firmware %s\n", fw_name); ++ if (request_firmware(&fw, fw_name, &pdev->dev)) + goto error; +- } + + *bfi_image = (u32 *)fw->data; + *bfi_image_size = fw->size/sizeof(u32); +--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +@@ -1036,12 +1036,8 @@ int t3_get_edc_fw(struct cphy *phy, int + fw_name = get_edc_fw_name(edc_idx); + if (fw_name) + ret = request_firmware(&fw, fw_name, &adapter->pdev->dev); +- if (ret < 0) { +- dev_err(&adapter->pdev->dev, +- "could not upgrade firmware: unable to load %s\n", +- fw_name); ++ if (ret) + return ret; +- } + + /* check size, take checksum in account */ + if (fw->size > size + 4) { +@@ -1078,11 +1074,8 @@ static int upgrade_fw(struct adapter *ad + struct device *dev = &adap->pdev->dev; + + ret = request_firmware(&fw, FW_FNAME, dev); +- if (ret < 0) { +- dev_err(dev, "could not upgrade firmware: unable to load %s\n", +- FW_FNAME); ++ if (ret) + return ret; +- } + ret = t3_load_fw(adap, fw->data, fw->size); + release_firmware(fw); + +@@ -1127,11 +1120,8 @@ static int update_tpsram(struct adapter + snprintf(buf, sizeof(buf), TPSRAM_NAME, rev); + + ret = request_firmware(&tpsram, buf, dev); +- if (ret < 0) { +- dev_err(dev, "could not load TP SRAM: unable to load %s\n", +- buf); ++ if (ret) + return ret; +- } + + ret = t3_check_tpsram(adap, tpsram->data, tpsram->size); + if (ret) +--- a/drivers/net/ethernet/intel/e100.c ++++ b/drivers/net/ethernet/intel/e100.c +@@ -1262,9 +1262,6 @@ static const struct firmware *e100_reque + + if (err) { + if (required) { +- netif_err(nic, probe, nic->netdev, +- "Failed to load firmware \"%s\": %d\n", +- fw_name, err); + return ERR_PTR(err); + } else { + netif_info(nic, probe, nic->netdev, +--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -580,8 +580,6 @@ static int myri10ge_load_hotplug_firmwar + unsigned i; + + if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { +- dev_err(dev, "Unable to load %s firmware image via hotplug\n", +- mgp->fw_name); + status = -EINVAL; + goto abort_with_nothing; + } +--- a/drivers/net/ethernet/smsc/smc91c92_cs.c ++++ b/drivers/net/ethernet/smsc/smc91c92_cs.c +@@ -647,10 +647,8 @@ static int osi_load_firmware(struct pcmc + int i, err; + + err = request_firmware(&fw, FIRMWARE_NAME, &link->dev); +- if (err) { +- pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME); ++ if (err) + return err; +- } + + /* Download the Seven of Diamonds firmware */ + for (i = 0; i < fw->size; i++) { +--- a/drivers/net/ethernet/sun/cassini.c ++++ b/drivers/net/ethernet/sun/cassini.c +@@ -793,11 +793,8 @@ static void cas_saturn_firmware_init(str + return; + + err = request_firmware(&fw, fw_name, &cp->pdev->dev); +- if (err) { +- pr_err("Failed to load firmware \"%s\"\n", +- fw_name); ++ if (err) + return; +- } + if (fw->size < 2) { + pr_err("bogus length %zu in \"%s\"\n", + fw->size, fw_name); +--- a/drivers/net/hamradio/yam.c ++++ b/drivers/net/hamradio/yam.c +@@ -357,11 +357,8 @@ static unsigned char *add_mcs(unsigned c + } + err = request_firmware(&fw, fw_name[predef], &pdev->dev); + platform_device_unregister(pdev); +- if (err) { +- printk(KERN_ERR "Failed to load firmware \"%s\"\n", +- fw_name[predef]); ++ if (err) + return NULL; +- } + if (fw->size != YAM_FPGA_SIZE) { + printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n", + fw->size, fw_name[predef]); +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -305,10 +305,8 @@ static int kaweth_download_firmware(stru + int ret; + + ret = request_firmware(&fw, fwname, &kaweth->dev->dev); +- if (ret) { +- dev_err(&kaweth->intf->dev, "Firmware request failed\n"); ++ if (ret) + return ret; +- } + + if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { + dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n", +--- a/drivers/net/wimax/i2400m/fw.c ++++ b/drivers/net/wimax/i2400m/fw.c +@@ -1578,11 +1578,8 @@ int i2400m_dev_bootstrap(struct i2400m * + } + d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr); + ret = request_firmware(&fw, fw_name, dev); +- if (ret < 0) { +- dev_err(dev, "fw %s: cannot load file: %d\n", +- fw_name, ret); ++ if (ret) + continue; +- } + i2400m->fw_name = fw_name; + ret = i2400m_fw_bootstrap(i2400m, fw, flags); + release_firmware(fw); +@@ -1625,8 +1622,6 @@ void i2400m_fw_cache(struct i2400m *i240 + kref_init(&i2400m_fw->kref); + result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev); + if (result < 0) { +- dev_err(dev, "firmware %s: failed to cache: %d\n", +- i2400m->fw_name, result); + kfree(i2400m_fw); + i2400m_fw = (void *) ~0; + } else +--- a/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -1216,9 +1216,6 @@ static void ath9k_hif_usb_firmware_cb(co + if (!ret) + return; + +- dev_err(&hif_dev->udev->dev, +- "ath9k_htc: Failed to get firmware %s\n", +- hif_dev->fw_name); + goto err_fw; + } + +--- a/drivers/net/wireless/ath/carl9170/usb.c ++++ b/drivers/net/wireless/ath/carl9170/usb.c +@@ -1029,7 +1029,6 @@ static void carl9170_usb_firmware_step2( + return; + } + +- dev_err(&ar->udev->dev, "firmware not found.\n"); + carl9170_usb_firmware_failed(ar); + } + +--- a/drivers/net/wireless/atmel/at76c50x-usb.c ++++ b/drivers/net/wireless/atmel/at76c50x-usb.c +@@ -1616,13 +1616,8 @@ static struct fwentry *at76_load_firmwar + + at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); + ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); +- if (ret < 0) { +- dev_err(&udev->dev, "firmware %s not found!\n", +- fwe->fwname); +- dev_err(&udev->dev, +- "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n"); ++ if (ret) + goto exit; +- } + + at76_dbg(DBG_FW, "got it."); + fwh = (struct at76_fw_header *)(fwe->fw->data); +--- a/drivers/net/wireless/atmel/atmel.c ++++ b/drivers/net/wireless/atmel/atmel.c +@@ -3892,12 +3892,8 @@ static int reset_atmel_card(struct net_d + strcpy(priv->firmware_id, "atmel_at76c502.bin"); + } + err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); +- if (err != 0) { +- printk(KERN_ALERT +- "%s: firmware %s is missing, cannot continue.\n", +- dev->name, priv->firmware_id); ++ if (err != 0) + return err; +- } + } else { + int fw_index = 0; + int success = 0; +--- a/drivers/net/wireless/broadcom/b43/main.c ++++ b/drivers/net/wireless/broadcom/b43/main.c +@@ -2245,19 +2245,8 @@ int b43_do_request_fw(struct b43_request + } + err = request_firmware(&ctx->blob, ctx->fwname, + ctx->dev->dev->dev); +- if (err == -ENOENT) { +- snprintf(ctx->errors[ctx->req_type], +- sizeof(ctx->errors[ctx->req_type]), +- "Firmware file \"%s\" not found\n", +- ctx->fwname); ++ if (err) + return err; +- } else if (err) { +- snprintf(ctx->errors[ctx->req_type], +- sizeof(ctx->errors[ctx->req_type]), +- "Firmware file \"%s\" request failed (err=%d)\n", +- ctx->fwname, err); +- return err; +- } + fw_ready: + if (ctx->blob->size < sizeof(struct b43_fw_header)) + goto err_format; +--- a/drivers/net/wireless/broadcom/b43legacy/main.c ++++ b/drivers/net/wireless/broadcom/b43legacy/main.c +@@ -1524,11 +1524,8 @@ static int do_request_fw(struct b43legac + } else { + err = request_firmware(fw, path, dev->dev->dev); + } +- if (err) { +- b43legacyerr(dev->wl, "Firmware file \"%s\" not found " +- "or load failed.\n", path); ++ if (err) + return err; +- } + if ((*fw)->size < sizeof(struct b43legacy_fw_header)) + goto err_format; + hdr = (struct b43legacy_fw_header *)((*fw)->data); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +@@ -377,19 +377,13 @@ static int brcms_request_fw(struct brcms + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); +- if (status) { +- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", +- KBUILD_MODNAME, fw_name); ++ if (status) + return status; +- } + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); +- if (status) { +- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", +- KBUILD_MODNAME, fw_name); ++ if (status) + return status; +- } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); + } +--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c +@@ -8370,12 +8370,8 @@ static int ipw2100_get_firmware(struct i + + rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev); + +- if (rc < 0) { +- printk(KERN_ERR DRV_NAME ": " +- "%s: Firmware '%s' not available or load failed.\n", +- priv->net_dev->name, fw_name); ++ if (rc) + return rc; +- } + IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, + fw->fw_entry->size); + +--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c +@@ -3396,10 +3396,8 @@ static int ipw_get_fw(struct ipw_priv *p + + /* ask firmware_class module to get the boot firmware off disk */ + rc = request_firmware(raw, name, &priv->pci_dev->dev); +- if (rc < 0) { +- IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc); ++ if (rc) + return rc; +- } + + if ((*raw)->size < sizeof(*fw)) { + IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size); +--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c ++++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c +@@ -1837,7 +1837,6 @@ il3945_read_ucode(struct il_priv *il) + sprintf(buf, "%s%u%s", name_pre, idx, ".ucode"); + ret = request_firmware(&ucode_raw, buf, &il->pci_dev->dev); + if (ret < 0) { +- IL_ERR("%s firmware file req failed: %d\n", buf, ret); + if (ret == -ENOENT) + continue; + else +--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -235,8 +235,6 @@ static int iwl_request_firmware(struct i + } + + if (drv->fw_index < cfg->ucode_api_min) { +- IWL_ERR(drv, "no suitable firmware found!\n"); +- + if (cfg->ucode_api_min == cfg->ucode_api_max) { + IWL_ERR(drv, "%s%d is required\n", cfg->fw_name_pre, + cfg->ucode_api_max); +--- a/drivers/net/wireless/intersil/orinoco/fw.c ++++ b/drivers/net/wireless/intersil/orinoco/fw.c +@@ -132,7 +132,6 @@ orinoco_dl_firmware(struct orinoco_priva + err = request_firmware(&fw_entry, firmware, priv->dev); + + if (err) { +- dev_err(dev, "Cannot find firmware %s\n", firmware); + err = -ENOENT; + goto free; + } +@@ -292,10 +291,8 @@ symbol_dl_firmware(struct orinoco_privat + const struct firmware *fw_entry; + + if (!orinoco_cached_fw_get(priv, true)) { +- if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) { +- dev_err(dev, "Cannot find firmware: %s\n", fw->pri_fw); ++ if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) + return -ENOENT; +- } + } else + fw_entry = orinoco_cached_fw_get(priv, true); + +@@ -311,10 +308,8 @@ symbol_dl_firmware(struct orinoco_privat + } + + if (!orinoco_cached_fw_get(priv, false)) { +- if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) { +- dev_err(dev, "Cannot find firmware: %s\n", fw->sta_fw); ++ if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) + return -ENOENT; +- } + } else + fw_entry = orinoco_cached_fw_get(priv, false); + +--- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c ++++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +@@ -1664,7 +1664,6 @@ static int ezusb_probe(struct usb_interf + if (ezusb_firmware_download(upriv, &firmware) < 0) + goto error; + } else { +- err("No firmware to download"); + goto error; + } + +--- a/drivers/net/wireless/intersil/p54/p54pci.c ++++ b/drivers/net/wireless/intersil/p54/p54pci.c +@@ -502,7 +502,6 @@ static void p54p_firmware_step2(const st + int err; + + if (!fw) { +- dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n"); + err = -ENOENT; + goto out; + } +--- a/drivers/net/wireless/intersil/p54/p54spi.c ++++ b/drivers/net/wireless/intersil/p54/p54spi.c +@@ -157,10 +157,8 @@ static int p54spi_request_firmware(struc + /* FIXME: should driver use it's own struct device? */ + ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev); + +- if (ret < 0) { +- dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret); ++ if (ret) + return ret; +- } + + ret = p54_parse_firmware(dev, priv->firmware); + if (ret) { +--- a/drivers/net/wireless/intersil/p54/p54usb.c ++++ b/drivers/net/wireless/intersil/p54/p54usb.c +@@ -929,7 +929,6 @@ static void p54u_load_firmware_cb(const + err = p54u_start_ops(priv); + } else { + err = -ENOENT; +- dev_err(&udev->dev, "Firmware not found.\n"); + } + + complete(&priv->fw_wait_load); +--- a/drivers/net/wireless/intersil/prism54/islpci_dev.c ++++ b/drivers/net/wireless/intersil/prism54/islpci_dev.c +@@ -80,12 +80,9 @@ isl_upload_firmware(islpci_private *priv + const u32 *fw_ptr; + + rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV); +- if (rc) { +- printk(KERN_ERR +- "%s: request_firmware() failed for '%s'\n", +- "prism54", priv->firmware); ++ if (rc) + return rc; +- } ++ + /* prepare the Direct Memory Base register */ + reg = ISL38XX_DEV_FIRMWARE_ADDRES; + +--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c ++++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c +@@ -818,8 +818,6 @@ static int if_usb_prog_firmware(struct l + kernel_param_lock(THIS_MODULE); + ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); + if (ret < 0) { +- pr_err("request_firmware() failed with %#x\n", ret); +- pr_err("firmware %s not found\n", lbtf_fw_name); + kernel_param_unlock(THIS_MODULE); + goto done; + } +--- a/drivers/net/wireless/marvell/mwifiex/main.c ++++ b/drivers/net/wireless/marvell/mwifiex/main.c +@@ -527,11 +527,8 @@ static int _mwifiex_fw_dpc(const struct + struct wireless_dev *wdev; + struct completion *fw_done = adapter->fw_done; + +- if (!firmware) { +- mwifiex_dbg(adapter, ERROR, +- "Failed to get firmware %s\n", adapter->fw_name); ++ if (!firmware) + goto err_dnld_fw; +- } + + memset(&fw, 0, sizeof(struct mwifiex_fw_image)); + adapter->firmware = firmware; +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -5727,16 +5727,12 @@ static int mwl8k_firmware_load_success(s + static void mwl8k_fw_state_machine(const struct firmware *fw, void *context) + { + struct mwl8k_priv *priv = context; +- struct mwl8k_device_info *di = priv->device_info; + int rc; + + switch (priv->fw_state) { + case FW_STATE_INIT: +- if (!fw) { +- printk(KERN_ERR "%s: Error requesting helper fw %s\n", +- pci_name(priv->pdev), di->helper_image); ++ if (!fw) + goto fail; +- } + priv->fw_helper = fw; + rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, + true); +@@ -5771,11 +5767,8 @@ static void mwl8k_fw_state_machine(const + break; + + case FW_STATE_LOADING_ALT: +- if (!fw) { +- printk(KERN_ERR "%s: Error requesting alt fw %s\n", +- pci_name(priv->pdev), di->helper_image); ++ if (!fw) + goto fail; +- } + priv->fw_ucode = fw; + rc = mwl8k_firmware_load_success(priv); + if (rc) +@@ -5813,10 +5806,8 @@ retry: + + /* Ask userland hotplug daemon for the device firmware */ + rc = mwl8k_request_firmware(priv, fw_image, nowait); +- if (rc) { +- wiphy_err(hw->wiphy, "Firmware files not found\n"); ++ if (rc) + return rc; +- } + + if (nowait) + return rc; +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c +@@ -38,10 +38,8 @@ static int rt2x00lib_request_firmware(st + rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); + + retval = request_firmware(&fw, fw_name, device); +- if (retval) { +- rt2x00_err(rt2x00dev, "Failed to request Firmware\n"); ++ if (retval) + return retval; +- } + + if (!fw || !fw->size || !fw->data) { + rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); +--- a/drivers/net/wireless/realtek/rtlwifi/core.c ++++ b/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -88,7 +88,6 @@ static void rtl_fw_do_work(const struct + if (!err) + goto found_alt; + } +- pr_err("Selected firmware is not available\n"); + rtlpriv->max_fw_size = 0; + goto exit; + } +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -63,13 +63,11 @@ static void rtl92se_fw_cb(const struct f + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_firmware *pfirmware = NULL; +- char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { +- pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; + return; + } +--- a/drivers/net/wireless/ti/wl1251/main.c ++++ b/drivers/net/wireless/ti/wl1251/main.c +@@ -57,10 +57,8 @@ static int wl1251_fetch_firmware(struct + + ret = request_firmware(&fw, WL1251_FW_NAME, dev); + +- if (ret < 0) { +- wl1251_error("could not get firmware: %d", ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1251_error("firmware size is not multiple of 32 bits: %zu", +@@ -96,10 +94,8 @@ static int wl1251_fetch_nvs(struct wl125 + + ret = request_firmware(&fw, WL1251_NVS_NAME, dev); + +- if (ret < 0) { +- wl1251_error("could not get nvs file: %d", ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1251_error("nvs size is not multiple of 32 bits: %zu", +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -764,10 +764,8 @@ static int wl12xx_fetch_firmware(struct + + ret = request_firmware(&fw, fw_name, wl->dev); + +- if (ret < 0) { +- wl1271_error("could not get firmware %s: %d", fw_name, ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1271_error("firmware size is not multiple of 32 bits: %zu", +--- a/drivers/net/wireless/zydas/zd1201.c ++++ b/drivers/net/wireless/zydas/zd1201.c +@@ -62,8 +62,6 @@ static int zd1201_fw_upload(struct usb_d + + err = request_firmware(&fw_entry, fwfile, &dev->dev); + if (err) { +- dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile); +- dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n"); + dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n"); + return err; + } +--- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c ++++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +@@ -108,16 +108,9 @@ static void int_urb_complete(struct urb + static int request_fw_file( + const struct firmware **fw, const char *name, struct device *device) + { +- int r; +- + dev_dbg_f(device, "fw name %s\n", name); + +- r = request_firmware(fw, name, device); +- if (r) +- dev_err(device, +- "Could not load firmware file %s. Error number %d\n", +- name, r); +- return r; ++ return request_firmware(fw, name, device); + } + + static inline u16 get_bcdDevice(const struct usb_device *udev) +--- a/drivers/scsi/advansys.c ++++ b/drivers/scsi/advansys.c +@@ -4103,8 +4103,6 @@ static int AscInitAsc1000Driver(ASC_DVC_ + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -4469,8 +4467,6 @@ static int AdvInitAsc3550Driver(ADV_DVC_ + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -4969,8 +4965,6 @@ static int AdvInitAsc38C0800Driver(ADV_D + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -5457,8 +5451,6 @@ static int AdvInitAsc38C1600Driver(ADV_D + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +--- a/drivers/scsi/aic94xx/aic94xx_init.c ++++ b/drivers/scsi/aic94xx/aic94xx_init.c +@@ -369,8 +369,6 @@ static ssize_t asd_store_update_bios(str + filename_ptr, + &asd_ha->pcidev->dev); + if (err) { +- asd_printk("Failed to load bios image file %s, error %d\n", +- filename_ptr, err); + err = FAIL_OPEN_BIOS_FILE; + goto out1; + } +--- a/drivers/scsi/aic94xx/aic94xx_seq.c ++++ b/drivers/scsi/aic94xx/aic94xx_seq.c +@@ -1302,11 +1302,8 @@ int asd_init_seqs(struct asd_ha_struct * + + err = asd_request_firmware(asd_ha); + +- if (err) { +- asd_printk("Failed to load sequencer firmware file %s, error %d\n", +- SAS_RAZOR_SEQUENCER_FW_FILE, err); ++ if (err) + return err; +- } + + err = asd_seq_download_seqs(asd_ha); + if (err) { +--- a/drivers/scsi/bfa/bfad.c ++++ b/drivers/scsi/bfa/bfad.c +@@ -1749,7 +1749,6 @@ bfad_read_firmware(struct pci_dev *pdev, + const struct firmware *fw; + + if (request_firmware(&fw, fw_name, &pdev->dev)) { +- printk(KERN_ALERT "Can't locate firmware %s\n", fw_name); + *bfi_image = NULL; + goto out; + } +--- a/drivers/scsi/ipr.c ++++ b/drivers/scsi/ipr.c +@@ -4102,10 +4102,8 @@ static ssize_t ipr_store_update_fw(struc + if (endline) + *endline = '\0'; + +- if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) { +- dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname); ++ if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) + return -EIO; +- } + + image_hdr = (struct ipr_ucode_image_header *)fw_entry->data; + +--- a/drivers/scsi/pm8001/pm8001_ctl.c ++++ b/drivers/scsi/pm8001/pm8001_ctl.c +@@ -841,9 +841,6 @@ static ssize_t pm8001_store_update_fw(st + pm8001_ha->dev); + + if (ret) { +- pm8001_dbg(pm8001_ha, FAIL, +- "Failed to load firmware image file %s, error %d\n", +- filename_ptr, ret); + pm8001_ha->fw_status = FAIL_OPEN_BIOS_FILE; + goto out; + } +--- a/drivers/scsi/qla1280.c ++++ b/drivers/scsi/qla1280.c +@@ -1514,8 +1514,6 @@ qla1280_request_firmware(struct scsi_qla + err = request_firmware(&fw, fwname, &ha->pdev->dev); + + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + fw = ERR_PTR(err); + goto unlock; + } +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -7935,10 +7935,6 @@ qla2x00_load_risc(scsi_qla_host_t *vha, + /* Load firmware blob. */ + blob = qla2x00_request_firmware(vha); + if (!blob) { +- ql_log(ql_log_info, vha, 0x0083, +- "Firmware image unavailable.\n"); +- ql_log(ql_log_info, vha, 0x0084, +- "Firmware images can be retrieved from: "QLA_FW_URL ".\n"); + return QLA_FUNCTION_FAILED; + } + +@@ -8041,9 +8037,6 @@ qla24xx_load_risc_blob(scsi_qla_host_t * + + blob = qla2x00_request_firmware(vha); + if (!blob) { +- ql_log(ql_log_warn, vha, 0x0092, +- "-> Firmware file not found.\n"); +- + return QLA_FUNCTION_FAILED; + } + +--- a/drivers/scsi/qla2xxx/qla_nx.c ++++ b/drivers/scsi/qla2xxx/qla_nx.c +@@ -2431,11 +2431,8 @@ try_blob_fw: + + /* Load firmware blob. */ + blob = ha->hablob = qla2x00_request_firmware(vha); +- if (!blob) { +- ql_log(ql_log_fatal, vha, 0x00a3, +- "Firmware image not present.\n"); ++ if (!blob) + goto fw_load_failed; +- } + + /* Validating firmware blob */ + if (qla82xx_validate_firmware_blob(vha, +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -7346,8 +7346,6 @@ qla2x00_request_firmware(scsi_qla_host_t + goto out; + + if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { +- ql_log(ql_log_warn, vha, 0x0063, +- "Failed to load firmware image (%s).\n", blob->name); + blob->fw = NULL; + blob = NULL; + } +--- a/drivers/scsi/qlogicpti.c ++++ b/drivers/scsi/qlogicpti.c +@@ -486,11 +486,8 @@ static int qlogicpti_load_firmware(struc + int i, timeout; + + err = request_firmware(&fw, fwname, &qpti->op->dev); +- if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); ++ if (err) + return err; +- } + if (fw->size % 2) { + printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", + fw->size, fwname); +--- a/drivers/staging/rtl8192u/r819xU_firmware.c ++++ b/drivers/staging/rtl8192u/r819xU_firmware.c +@@ -240,10 +240,8 @@ bool init_firmware(struct net_device *de + */ + if (rst_opt == OPT_SYSTEM_RESET) { + rc = request_firmware(&fw_entry, fw_name[init_step], &priv->udev->dev); +- if (rc < 0) { +- RT_TRACE(COMP_ERR, "request firmware fail!\n"); ++ if (rc) + goto download_firmware_fail; +- } + + if (fw_entry->size > sizeof(pfirmware->firmware_buf)) { + RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); +--- a/drivers/staging/rtl8712/hal_init.c ++++ b/drivers/staging/rtl8712/hal_init.c +@@ -60,8 +60,6 @@ int rtl871x_load_fw(struct _adapter *pad + dev_info(dev, "r8712u: Loading firmware from \"%s\"\n", firmware_file); + rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev, + GFP_KERNEL, padapter, rtl871x_load_fw_cb); +- if (rc) +- dev_err(dev, "r8712u: Firmware request error %d\n", rc); + return rc; + } + MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); +--- a/drivers/staging/vt6656/main_usb.c ++++ b/drivers/staging/vt6656/main_usb.c +@@ -109,11 +109,8 @@ static int vnt_download_firmware(struct + dev_dbg(dev, "---->Download firmware\n"); + + ret = request_firmware(&fw, FIRMWARE_NAME, dev); +- if (ret) { +- dev_err(dev, "firmware file %s request failed (%d)\n", +- FIRMWARE_NAME, ret); ++ if (ret) + goto end; +- } + + for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) { + length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE); +--- a/drivers/tty/cyclades.c ++++ b/drivers/tty/cyclades.c +@@ -3484,10 +3484,8 @@ static int cyz_load_fw(struct pci_dev *p + int retval; + + retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev); +- if (retval) { +- dev_err(&pdev->dev, "can't get firmware\n"); ++ if (retval) + goto err; +- } + + /* Check whether the firmware is already loaded and running. If + positive, skip this board */ +--- a/drivers/tty/moxa.c ++++ b/drivers/tty/moxa.c +@@ -854,13 +854,8 @@ static int moxa_init_board(struct moxa_b + } + + ret = request_firmware(&fw, file, dev); +- if (ret) { +- printk(KERN_ERR "MOXA: request_firmware failed. Make sure " +- "you've placed '%s' file into your firmware " +- "loader directory (e.g. /lib/firmware)\n", +- file); ++ if (ret) + goto err_free; +- } + + ret = moxa_load_fw(brd, fw); + +--- a/drivers/tty/serial/icom.c ++++ b/drivers/tty/serial/icom.c +@@ -362,7 +362,6 @@ static void load_code(struct icom_port * + + /* Load Call Setup into Adapter */ + if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +@@ -382,7 +381,6 @@ static void load_code(struct icom_port * + + /* Load Resident DCE portion of Adapter */ + if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +@@ -427,7 +425,6 @@ static void load_code(struct icom_port * + } + + if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +--- a/drivers/tty/serial/ucc_uart.c ++++ b/drivers/tty/serial/ucc_uart.c +@@ -1161,10 +1161,8 @@ static void uart_firmware_cont(const str + struct device *dev = context; + int ret; + +- if (!fw) { +- dev_err(dev, "firmware not found\n"); ++ if (!fw) + return; +- } + + firmware = (struct qe_firmware *) fw->data; + +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -1087,8 +1087,6 @@ static int cxacru_find_firmware(struct c + return -ENOENT; + } + +- usb_info(usbatm, "found firmware %s\n", buf); +- + return 0; + } + +--- a/drivers/usb/atm/ueagle-atm.c ++++ b/drivers/usb/atm/ueagle-atm.c +@@ -606,10 +606,8 @@ static void uea_upload_pre_firmware(cons + int ret, size; + + uea_enters(usb); +- if (!fw_entry) { +- uea_err(usb, "firmware is not available\n"); ++ if (!fw_entry) + goto err; +- } + + pfw = fw_entry->data; + size = fw_entry->size; +@@ -704,10 +702,6 @@ static int uea_load_firmware(struct usb_ + ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, + GFP_KERNEL, usb, + uea_upload_pre_firmware); +- if (ret) +- uea_err(usb, "firmware %s is not available\n", fw_name); +- else +- uea_info(usb, "loading firmware %s\n", fw_name); + + uea_leaves(usb); + return ret; +@@ -869,12 +863,8 @@ static int request_dsp(struct uea_softc + } + + ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); +- if (ret < 0) { +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- dsp_name, ret); ++ if (ret) + return ret; +- } + + if (UEA_CHIP_VERSION(sc) == EAGLE_IV) + ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); +@@ -1587,12 +1577,8 @@ static int request_cmvs_old(struct uea_s + + cmvs_file_name(sc, cmv_name, 1); + ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); +- if (ret < 0) { +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- cmv_name, ret); ++ if (ret) + return ret; +- } + + data = (u8 *) (*fw)->data; + size = (*fw)->size; +@@ -1629,9 +1615,6 @@ static int request_cmvs(struct uea_softc + "try to get older cmvs\n", cmv_name); + return request_cmvs_old(sc, cmvs, fw); + } +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- cmv_name, ret); + return ret; + } + +@@ -1914,11 +1897,8 @@ static int load_XILINX_firmware(struct u + uea_enters(INS_TO_USBDEV(sc)); + + ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); +- if (ret) { +- uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n", +- fw_name); ++ if (ret) + goto err0; +- } + + pfw = fw_entry->data; + size = fw_entry->size; +--- a/drivers/usb/misc/emi26.c ++++ b/drivers/usb/misc/emi26.c +@@ -85,21 +85,17 @@ static int emi26_load_firmware (struct u + + err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); + if (err) +- goto nofw; ++ goto wraperr; + + err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", + &dev->dev); + if (err) +- goto nofw; ++ goto wraperr; + + err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", + &dev->dev); +- if (err) { +- nofw: +- dev_err(&dev->dev, "%s - request_firmware() failed\n", +- __func__); ++ if (err) + goto wraperr; +- } + + /* Assert reset (stop the CPU in the EMI) */ + err = emi26_set_reset(dev,1); +--- a/drivers/usb/misc/ezusb.c ++++ b/drivers/usb/misc/ezusb.c +@@ -76,12 +76,8 @@ static int ezusb_ihex_firmware_download( + const struct ihex_binrec *record; + + if (request_ihex_firmware(&firmware, firmware_path, +- &dev->dev)) { +- dev_err(&dev->dev, +- "%s - request \"%s\" failed\n", +- __func__, firmware_path); ++ &dev->dev)) + goto out; +- } + + ret = ezusb_set_reset(dev, fx.cpucs_reg, 0); + if (ret < 0) +--- a/drivers/usb/misc/isight_firmware.c ++++ b/drivers/usb/misc/isight_firmware.c +@@ -45,7 +45,6 @@ static int isight_firmware_load(struct u + return -ENOMEM; + + if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { +- printk(KERN_ERR "Unable to load isight firmware\n"); + ret = -ENODEV; + goto out; + } +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -375,11 +375,8 @@ static void update_edgeport_E2PROM(struc + + response = request_ihex_firmware(&fw, fw_name, + &edge_serial->serial->dev->dev); +- if (response) { +- dev_err(dev, "Failed to load image \"%s\" err %d\n", +- fw_name, response); ++ if (response) + return; +- } + + rec = (const struct ihex_binrec *)fw->data; + BootMajorVersion = rec->data[0]; +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -1010,8 +1010,6 @@ static int download_fw(struct edgeport_s + + status = request_firmware(&fw, fw_name, dev); + if (status) { +- dev_err(dev, "Failed to load image \"%s\" err %d\n", +- fw_name, status); + return status; + } + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -1663,10 +1663,8 @@ static int ti_download_firmware(struct t + } + + check_firmware: +- if (status) { +- dev_err(&dev->dev, "%s - firmware not found\n", __func__); ++ if (status) + return -ENOENT; +- } + if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { + dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size); + release_firmware(fw_p); +--- a/drivers/video/fbdev/broadsheetfb.c ++++ b/drivers/video/fbdev/broadsheetfb.c +@@ -743,10 +743,8 @@ static ssize_t broadsheet_loadstore_wave + return -EINVAL; + + err = request_firmware(&fw_entry, "broadsheet.wbf", dev); +- if (err < 0) { +- dev_err(dev, "Failed to get broadsheet waveform\n"); ++ if (err) + goto err_failed; +- } + + /* try to enforce reasonable min max on waveform */ + if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) { +--- a/drivers/video/fbdev/metronomefb.c ++++ b/drivers/video/fbdev/metronomefb.c +@@ -679,10 +679,8 @@ static int metronomefb_probe(struct plat + a) request the waveform file from userspace + b) process waveform and decode into metromem */ + retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); +- if (retval < 0) { +- dev_err(&dev->dev, "Failed to get waveform\n"); ++ if (retval) + goto err_csum_table; +- } + + retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31, + par); +--- a/sound/drivers/vx/vx_hwdep.c ++++ b/sound/drivers/vx/vx_hwdep.c +@@ -58,10 +58,8 @@ int snd_vx_setup_firmware(struct vx_core + if (! fw_files[chip->type][i]) + continue; + sprintf(path, "vx/%s", fw_files[chip->type][i]); +- if (request_firmware(&fw, path, chip->dev)) { +- snd_printk(KERN_ERR "vx: can't load firmware %s\n", path); ++ if (request_firmware(&fw, path, chip->dev)) + return -ENOENT; +- } + err = chip->ops->load_dsp(chip, i, fw); + if (err < 0) { + release_firmware(fw); +--- a/sound/isa/msnd/msnd_pinnacle.c ++++ b/sound/isa/msnd/msnd_pinnacle.c +@@ -376,15 +376,11 @@ static int upload_dsp_code(struct snd_ca + outb(HPBLKSEL_0, chip->io + HP_BLKS); + + err = request_firmware(&init_fw, INITCODEFILE, card->dev); +- if (err < 0) { +- printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE); ++ if (err) + goto cleanup1; +- } + err = request_firmware(&perm_fw, PERMCODEFILE, card->dev); +- if (err < 0) { +- printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE); ++ if (err) + goto cleanup; +- } + + memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size); + if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) { +--- a/sound/isa/sscape.c ++++ b/sound/isa/sscape.c +@@ -531,10 +531,8 @@ static int sscape_upload_bootblock(struc + int ret; + + ret = request_firmware(&init_fw, "scope.cod", card->dev); +- if (ret < 0) { +- snd_printk(KERN_ERR "sscape: Error loading scope.cod"); ++ if (ret) + return ret; +- } + ret = upload_dma_data(sscape, init_fw->data, init_fw->size); + + release_firmware(init_fw); +@@ -571,11 +569,8 @@ static int sscape_upload_microcode(struc + snprintf(name, sizeof(name), "sndscape.co%d", version); + + err = request_firmware(&init_fw, name, card->dev); +- if (err < 0) { +- snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d", +- version); ++ if (err) + return err; +- } + err = upload_dma_data(sscape, init_fw->data, init_fw->size); + if (err == 0) + snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n", +--- a/sound/isa/wavefront/wavefront_synth.c ++++ b/sound/isa/wavefront/wavefront_synth.c +@@ -1959,10 +1959,8 @@ wavefront_download_firmware (snd_wavefro + const struct firmware *firmware; + + err = request_firmware(&firmware, path, dev->card->dev); +- if (err < 0) { +- snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path); ++ if (err) + return 1; +- } + + len = 0; + buf = firmware->data; +--- a/sound/pci/asihpi/hpidspcd.c ++++ b/sound/pci/asihpi/hpidspcd.c +@@ -35,8 +35,6 @@ short hpi_dsp_code_open(u32 adapter, voi + err = request_firmware(&firmware, fw_name, &dev->dev); + + if (err || !firmware) { +- dev_err(&dev->dev, "%d, request_firmware failed for %s\n", +- err, fw_name); + goto error1; + } + if (firmware->size < sizeof(header)) { +--- a/sound/pci/cs46xx/cs46xx_lib.c ++++ b/sound/pci/cs46xx/cs46xx_lib.c +@@ -3235,11 +3235,8 @@ int snd_cs46xx_start_dsp(struct snd_cs46 + #ifdef CONFIG_SND_CS46XX_NEW_DSP + for (i = 0; i < CS46XX_DSP_MODULES; i++) { + err = load_firmware(chip, &chip->modules[i], module_names[i]); +- if (err < 0) { +- dev_err(chip->card->dev, "firmware load error [%s]\n", +- module_names[i]); ++ if (err < 0) + return err; +- } + err = cs46xx_dsp_load_module(chip, chip->modules[i]); + if (err < 0) { + dev_err(chip->card->dev, "image download error [%s]\n", +--- a/sound/pci/echoaudio/echoaudio.c ++++ b/sound/pci/echoaudio/echoaudio.c +@@ -49,11 +49,8 @@ static int get_firmware(const struct fir + "firmware requested: %s\n", card_fw[fw_index].data); + snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); + err = request_firmware(fw_entry, name, &chip->pci->dev); +- if (err < 0) +- dev_err(chip->card->dev, +- "get_firmware(): Firmware not available (%d)\n", err); + #ifdef CONFIG_PM_SLEEP +- else ++ if (!err) + chip->fw_cache[fw_index] = *fw_entry; + #endif + return err; +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -873,10 +873,8 @@ static int snd_emu10k1_emu1010_init(stru + dev_info(emu->card->dev, "emu1010: EMU_HANA_ID = 0x%x\n", reg); + + err = snd_emu1010_load_firmware(emu, 0, &emu->firmware); +- if (err < 0) { +- dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n"); ++ if (err < 0) + return err; +- } + + /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ + snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); +--- a/sound/pci/hda/hda_intel.c ++++ b/sound/pci/hda/hda_intel.c +@@ -2057,8 +2057,6 @@ static void azx_firmware_cb(const struct + + if (fw) + chip->fw = fw; +- else +- dev_err(card->dev, "Cannot load firmware, continue without patching\n"); + if (!chip->disabled) { + /* continue probing */ + azx_probe_continue(chip); +--- a/sound/pci/korg1212/korg1212.c ++++ b/sound/pci/korg1212/korg1212.c +@@ -2335,7 +2335,6 @@ static int snd_korg1212_create(struct sn + + err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); + if (err < 0) { +- snd_printk(KERN_ERR "firmware not available\n"); + snd_korg1212_free(korg1212); + return err; + } +--- a/sound/pci/mixart/mixart_hwdep.c ++++ b/sound/pci/mixart/mixart_hwdep.c +@@ -558,11 +558,8 @@ int snd_mixart_setup_firmware(struct mix + + for (i = 0; i < 3; i++) { + sprintf(path, "mixart/%s", fw_files[i]); +- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { +- dev_err(&mgr->pci->dev, +- "miXart: can't load firmware %s\n", path); ++ if (request_firmware(&fw_entry, path, &mgr->pci->dev)) + return -ENOENT; +- } + /* fake hwdep dsp record */ + err = mixart_dsp_load(mgr, i, fw_entry); + release_firmware(fw_entry); +--- a/sound/pci/pcxhr/pcxhr_hwdep.c ++++ b/sound/pci/pcxhr/pcxhr_hwdep.c +@@ -372,12 +372,8 @@ int pcxhr_setup_firmware(struct pcxhr_mg + if (!fw_files[fw_set][i]) + continue; + sprintf(path, "pcxhr/%s", fw_files[fw_set][i]); +- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { +- dev_err(&mgr->pci->dev, +- "pcxhr: can't load firmware %s\n", +- path); ++ if (request_firmware(&fw_entry, path, &mgr->pci->dev)) + return -ENOENT; +- } + /* fake hwdep dsp record */ + err = pcxhr_dsp_load(mgr, i, fw_entry); + release_firmware(fw_entry); +--- a/sound/pci/riptide/riptide.c ++++ b/sound/pci/riptide/riptide.c +@@ -1217,11 +1217,8 @@ static int try_to_load_firmware(struct c + if (!chip->fw_entry) { + err = request_firmware(&chip->fw_entry, "riptide.hex", + &chip->pci->dev); +- if (err) { +- snd_printk(KERN_ERR +- "Riptide: Firmware not available %d\n", err); ++ if (err) + return -EIO; +- } + } + err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size); + if (err) { +--- a/sound/pci/rme9652/hdsp.c ++++ b/sound/pci/rme9652/hdsp.c +@@ -5111,11 +5111,8 @@ static int hdsp_request_fw_loader(struct + return -EINVAL; + } + +- if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) { +- dev_err(hdsp->card->dev, +- "cannot load firmware %s\n", fwfile); ++ if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) + return -ENOENT; +- } + if (fw->size < HDSP_FIRMWARE_SIZE) { + dev_err(hdsp->card->dev, + "too short firmware size %d (expected %d)\n", +--- a/sound/soc/codecs/wm2000.c ++++ b/sound/soc/codecs/wm2000.c +@@ -894,10 +894,8 @@ static int wm2000_i2c_probe(struct i2c_c + } + + ret = request_firmware(&fw, filename, &i2c->dev); +- if (ret != 0) { +- dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); ++ if (ret != 0) + goto err_supplies; +- } + + /* Pre-cook the concatenation of the register address onto the image */ + wm2000->anc_download_size = fw->size + 2; +--- a/sound/usb/6fire/firmware.c ++++ b/sound/usb/6fire/firmware.c +@@ -203,8 +203,6 @@ static int usb6fire_fw_ezusb_upload( + ret = request_firmware(&fw, fwname, &device->dev); + if (ret < 0) { + kfree(rec); +- dev_err(&intf->dev, +- "error requesting ezusb firmware %s.\n", fwname); + return ret; + } + ret = usb6fire_fw_ihex_init(fw, rec); +@@ -280,8 +278,6 @@ static int usb6fire_fw_fpga_upload( + + ret = request_firmware(&fw, fwname, &device->dev); + if (ret < 0) { +- dev_err(&intf->dev, "unable to get fpga firmware %s.\n", +- fwname); + kfree(buffer); + return -EIO; + } diff --git a/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch new file mode 100644 index 000000000..092a74496 --- /dev/null +++ b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch @@ -0,0 +1,83 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: firmware_class: Log every success and failure against given device +Date: Sun, 09 Dec 2012 16:02:00 +0000 +Forwarded: no + +The hundreds of users of request_firmware() have nearly as many +different log formats for reporting failures. They also have only the +vaguest hint as to what went wrong; only firmware_class really knows +that. Therefore, add specific log messages for the failure modes that +aren't currently logged. + +In case of a driver that tries multiple names, this may result in the +impression that it failed to initialise. Therefore, also log successes. + +This makes many error messages in drivers redundant, which will be +removed in later patches. + +This does not cover the case where we fall back to a user-mode helper +(which is no longer enabled in Debian). + +NOTE: hw-detect will depend on the "firmware: failed to load %s (%d)\n" +format to detect missing firmware. +--- + drivers/base/firmware_loader/fallback.c | 2 +- + drivers/base/firmware_loader/main.c | 17 ++++++++--------- + 2 files changed, 9 insertions(+), 10 deletions(-) + +--- a/drivers/base/firmware_loader/fallback.c ++++ b/drivers/base/firmware_loader/fallback.c +@@ -558,7 +558,7 @@ static int fw_load_from_user_helper(stru + if (opt_flags & FW_OPT_NOWAIT) { + timeout = usermodehelper_read_lock_wait(timeout); + if (!timeout) { +- dev_dbg(device, "firmware: %s loading timed out\n", ++ dev_err(device, "firmware: %s loading timed out\n", + name); + return -EBUSY; + } +--- a/drivers/base/firmware_loader/main.c ++++ b/drivers/base/firmware_loader/main.c +@@ -535,18 +535,15 @@ fw_get_filesystem_firmware(struct device + file_size_ptr, + READING_FIRMWARE); + if (rc < 0) { +- if (rc != -ENOENT) +- dev_warn(device, "loading %s failed with error %d\n", +- path, rc); +- else +- dev_dbg(device, "loading %s failed for no such file or directory.\n", +- path); ++ dev_dbg(device, "loading %s failed with error %d\n", ++ path, rc); + continue; + } + size = rc; + rc = 0; + +- dev_dbg(device, "Loading firmware from %s\n", path); ++ dev_info(device, "firmware: direct-loading firmware %s\n", ++ fw_priv->fw_name); + if (decompress) { + dev_dbg(device, "f/w decompressing %s\n", + fw_priv->fw_name); +@@ -559,8 +556,6 @@ fw_get_filesystem_firmware(struct device + continue; + } + } else { +- dev_dbg(device, "direct-loading %s\n", +- fw_priv->fw_name); + if (!fw_priv->data) + fw_priv->data = buffer; + fw_priv->size = size; +@@ -570,6 +565,10 @@ fw_get_filesystem_firmware(struct device + } + __putname(path); + ++ if (rc) ++ dev_err(device, "firmware: failed to load %s (%d)\n", ++ fw_priv->fw_name, rc); ++ + return rc; + } + diff --git a/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch new file mode 100644 index 000000000..540a1341c --- /dev/null +++ b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch @@ -0,0 +1,70 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 13 Apr 2016 21:48:06 +0100 +Subject: fs: Add MODULE_SOFTDEP declarations for hard-coded crypto drivers +Bug-Debian: https://bugs.debian.org/819725 +Forwarded: http://mid.gmane.org/20160517133631.GF7555@decadent.org.uk + +This helps initramfs builders and other tools to find the full +dependencies of a module. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +--- + fs/btrfs/super.c | 2 +- + fs/ext4/super.c | 2 +- + fs/f2fs/super.c | 1 + + fs/jbd2/journal.c | 1 + + fs/nfsd/nfsctl.c | 3 +++ + 5 files changed, 7 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2597,7 +2597,7 @@ late_initcall(init_btrfs_fs); + module_exit(exit_btrfs_fs) + + MODULE_LICENSE("GPL"); +-MODULE_SOFTDEP("pre: crc32c"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); + MODULE_SOFTDEP("pre: xxhash64"); + MODULE_SOFTDEP("pre: sha256"); + MODULE_SOFTDEP("pre: blake2b-256"); +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -6746,6 +6746,6 @@ static void __exit ext4_exit_fs(void) + MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); + MODULE_DESCRIPTION("Fourth Extended Filesystem"); + MODULE_LICENSE("GPL"); +-MODULE_SOFTDEP("pre: crc32c"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); + module_init(ext4_init_fs) + module_exit(ext4_exit_fs) +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -4122,5 +4122,5 @@ module_exit(exit_f2fs_fs) + MODULE_AUTHOR("Samsung Electronics's Praesto Team"); + MODULE_DESCRIPTION("Flash Friendly File System"); + MODULE_LICENSE("GPL"); +-MODULE_SOFTDEP("pre: crc32"); ++MODULE_SOFTDEP("pre: crypto-crc32"); + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -3012,6 +3012,7 @@ static void __exit journal_exit(void) + } + + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); + module_init(journal_init); + module_exit(journal_exit); + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1580,5 +1580,8 @@ static void __exit exit_nfsd(void) + + MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); + MODULE_LICENSE("GPL"); ++#ifdef CONFIG_NFSD_V4 ++MODULE_SOFTDEP("pre: crypto-md5"); ++#endif + module_init(init_nfsd) + module_exit(exit_nfsd) diff --git a/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch new file mode 100644 index 000000000..820479896 --- /dev/null +++ b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch @@ -0,0 +1,23 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: kbuild: Fix recordmcount dependency for OOT modules +Date: Mon, 08 Sep 2014 18:31:24 +0100 +Forwarded: no + +We never rebuild anything in-tree when building an out-of-tree +modules, so external modules should not depend on the recordmcount +sources. + +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -232,6 +232,11 @@ cmd_record_mcount = \ + endif # CC_USING_RECORD_MCOUNT + endif # CONFIG_FTRACE_MCOUNT_RECORD + ++# Don't require recordmcount source for an OOT build. ++ifdef KBUILD_EXTMOD ++recordmcount_source := ++endif ++ + ifdef CONFIG_STACK_VALIDATION + ifneq ($(SKIP_STACK_VALIDATION),1) + diff --git a/debian/patches/bugfix/all/libcpupower-hide-private-function.patch b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch new file mode 100644 index 000000000..ac76e638e --- /dev/null +++ b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch @@ -0,0 +1,20 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 01 Dec 2018 19:22:50 +0000 +Subject: libcpupower: Hide private function + +cpupower_read_sysfs() (previously known as sysfs_read_file()) is an +internal function in libcpupower and should not be exported when +libcpupower is a shared library. Change its visibility to "hidden". + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/tools/power/cpupower/lib/cpupower.c ++++ b/tools/power/cpupower/lib/cpupower.c +@@ -15,6 +15,7 @@ + #include "cpupower.h" + #include "cpupower_intern.h" + ++__attribute__((visibility("hidden"))) + unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen) + { + int fd; diff --git a/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch new file mode 100644 index 000000000..2ab62688a --- /dev/null +++ b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch @@ -0,0 +1,23 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 02 Dec 2016 23:06:18 +0000 +Subject: module: Disable matching missing version CRC +Forwarded: not-needed + +This partly reverts commit cd3caefb4663e3811d37cc2afad3cce642d60061. +We want to fail closed if a symbol version CRC is missing, as the +alternative may allow subverting module signing. +--- +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -1313,9 +1313,8 @@ static int check_version(const struct lo + goto bad_version; + } + +- /* Broken toolchain. Warn once, then let it go.. */ +- pr_warn_once("%s: no symbol version for %s\n", info->name, symname); +- return 1; ++ pr_warn("%s: no symbol version for %s\n", info->name, symname); ++ return 0; + + bad_version: + pr_warn("%s: disagrees about version of symbol %s\n", diff --git a/debian/patches/bugfix/all/netfilter-nf_tables-reject-QUEUE-DROP-verdict-parame.patch b/debian/patches/bugfix/all/netfilter-nf_tables-reject-QUEUE-DROP-verdict-parame.patch new file mode 100644 index 000000000..a6e35b7f2 --- /dev/null +++ b/debian/patches/bugfix/all/netfilter-nf_tables-reject-QUEUE-DROP-verdict-parame.patch @@ -0,0 +1,73 @@ +From: Florian Westphal <fw@strlen.de> +Date: Sat, 20 Jan 2024 22:50:04 +0100 +Subject: netfilter: nf_tables: reject QUEUE/DROP verdict parameters +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=11351dcb86e3eec82492e20a63bb36f5a340dc85 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2024-1086 + +commit f342de4e2f33e0e39165d8639387aa6c19dff660 upstream. + +This reverts commit e0abdadcc6e1. + +core.c:nf_hook_slow assumes that the upper 16 bits of NF_DROP +verdicts contain a valid errno, i.e. -EPERM, -EHOSTUNREACH or similar, +or 0. + +Due to the reverted commit, its possible to provide a positive +value, e.g. NF_ACCEPT (1), which results in use-after-free. + +Its not clear to me why this commit was made. + +NF_QUEUE is not used by nftables; "queue" rules in nftables +will result in use of "nft_queue" expression. + +If we later need to allow specifiying errno values from userspace +(do not know why), this has to call NF_DROP_GETERR and check that +"err <= 0" holds true. + +Fixes: e0abdadcc6e1 ("netfilter: nf_tables: accept QUEUE/DROP verdict parameters") +Cc: stable@vger.kernel.org +Reported-by: Notselwyn <notselwyn@pwning.tech> +Signed-off-by: Florian Westphal <fw@strlen.de> +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + net/netfilter/nf_tables_api.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 0d0b76a5ddfa..f586e8b3c6cf 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -9340,16 +9340,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, + data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); + + switch (data->verdict.code) { +- default: +- switch (data->verdict.code & NF_VERDICT_MASK) { +- case NF_ACCEPT: +- case NF_DROP: +- case NF_QUEUE: +- break; +- default: +- return -EINVAL; +- } +- fallthrough; ++ case NF_ACCEPT: ++ case NF_DROP: ++ case NF_QUEUE: ++ break; + case NFT_CONTINUE: + case NFT_BREAK: + case NFT_RETURN: +@@ -9384,6 +9378,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, + + data->verdict.chain = chain; + break; ++ default: ++ return -EINVAL; + } + + desc->len = sizeof(data->verdict); +-- +2.43.0 + diff --git a/debian/patches/bugfix/all/ovl-fail-on-invalid-uid-gid-mapping-at-copy-up.patch b/debian/patches/bugfix/all/ovl-fail-on-invalid-uid-gid-mapping-at-copy-up.patch new file mode 100644 index 000000000..368787579 --- /dev/null +++ b/debian/patches/bugfix/all/ovl-fail-on-invalid-uid-gid-mapping-at-copy-up.patch @@ -0,0 +1,49 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Tue, 24 Jan 2023 16:41:18 +0100 +Subject: ovl: fail on invalid uid/gid mapping at copy up +Origin: https://git.kernel.org/linus/4f11ada10d0ad3fd53e2bd67806351de63a4f9c3 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2023-0386 + +If st_uid/st_gid doesn't have a mapping in the mounter's user_ns, then +copy-up should fail, just like it would fail if the mounter task was doing +the copy using "cp -a". + +There's a corner case where the "cp -a" would succeed but copy up fail: if +there's a mapping of the invalid uid/gid (65534 by default) in the user +namespace. This is because stat(2) will return this value if the mapping +doesn't exist in the current user_ns and "cp -a" will in turn be able to +create a file with this uid/gid. + +This behavior would be inconsistent with POSIX ACL's, which return -1 for +invalid uid/gid which result in a failed copy. + +For consistency and simplicity fail the copy of the st_uid/st_gid are +invalid. + +Fixes: 459c7c565ac3 ("ovl: unprivieged mounts") +Cc: <stable@vger.kernel.org> # v5.11 +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Reviewed-by: Christian Brauner <brauner@kernel.org> +Reviewed-by: Seth Forshee <sforshee@kernel.org> +--- + fs/overlayfs/copy_up.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 140f2742074d..c14e90764e35 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -1011,6 +1011,10 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry, + if (err) + return err; + ++ if (!kuid_has_mapping(current_user_ns(), ctx.stat.uid) || ++ !kgid_has_mapping(current_user_ns(), ctx.stat.gid)) ++ return -EOVERFLOW; ++ + ctx.metacopy = ovl_need_meta_copy_up(dentry, ctx.stat.mode, flags); + + if (parent) { +-- +2.40.1 + diff --git a/debian/patches/bugfix/all/partially-revert-net-socket-implement-64-bit-timestamps.patch b/debian/patches/bugfix/all/partially-revert-net-socket-implement-64-bit-timestamps.patch new file mode 100644 index 000000000..7367a1416 --- /dev/null +++ b/debian/patches/bugfix/all/partially-revert-net-socket-implement-64-bit-timestamps.patch @@ -0,0 +1,140 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 20 Aug 2019 18:12:35 +0100 +Subject: Partially revert "net: socket: implement 64-bit timestamps" + +The introduction of SIOCGSTAMP{,NS}_OLD and move of SICOGSTAMP{,NS} to +a different header has caused build failures for various user-space +programs including qemu and suricata. It also causes a test failure +for glibc. + +For now, remove the _OLD suffix on the old ioctl numbers and require +programs using 64-bit timestamps to explicitly use SIOCGSTAMP{,NS}_NEW. + +References: https://lore.kernel.org/lkml/af0eb47a-5b98-1bd9-3e8d-652e7f28b01f@de.ibm.com/ +References: https://bugs.debian.org/934316 +References: https://ci.debian.net/data/autopkgtest/testing/amd64/g/glibc/2772289/log.gz +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/alpha/include/uapi/asm/sockios.h ++++ b/arch/alpha/include/uapi/asm/sockios.h +@@ -11,7 +11,7 @@ + #define SIOCSPGRP _IOW('s', 8, pid_t) + #define SIOCGPGRP _IOR('s', 9, pid_t) + +-#define SIOCGSTAMP_OLD 0x8906 /* Get stamp (timeval) */ +-#define SIOCGSTAMPNS_OLD 0x8907 /* Get stamp (timespec) */ ++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + + #endif /* _ASM_ALPHA_SOCKIOS_H */ +--- a/arch/mips/include/uapi/asm/sockios.h ++++ b/arch/mips/include/uapi/asm/sockios.h +@@ -21,7 +21,7 @@ + #define SIOCSPGRP _IOW('s', 8, pid_t) + #define SIOCGPGRP _IOR('s', 9, pid_t) + +-#define SIOCGSTAMP_OLD 0x8906 /* Get stamp (timeval) */ +-#define SIOCGSTAMPNS_OLD 0x8907 /* Get stamp (timespec) */ ++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + + #endif /* _ASM_SOCKIOS_H */ +--- a/arch/sh/include/uapi/asm/sockios.h ++++ b/arch/sh/include/uapi/asm/sockios.h +@@ -12,7 +12,6 @@ + #define SIOCSPGRP _IOW('s', 8, pid_t) + #define SIOCGPGRP _IOR('s', 9, pid_t) + +-#define SIOCGSTAMP_OLD _IOR('s', 100, struct __kernel_old_timeval) /* Get stamp (timeval) */ +-#define SIOCGSTAMPNS_OLD _IOR('s', 101, struct __kernel_old_timespec) /* Get stamp (timespec) */ +- ++#define SIOCGSTAMP _IOR('s', 100, struct __kernel_old_timeval) /* Get stamp (timeval) */ ++#define SIOCGSTAMPNS _IOR('s', 101, struct __kernel_old_timespec) /* Get stamp (timespec) */ + #endif /* __ASM_SH_SOCKIOS_H */ +--- a/arch/xtensa/include/uapi/asm/sockios.h ++++ b/arch/xtensa/include/uapi/asm/sockios.h +@@ -26,7 +26,7 @@ + #define SIOCSPGRP _IOW('s', 8, pid_t) + #define SIOCGPGRP _IOR('s', 9, pid_t) + +-#define SIOCGSTAMP_OLD 0x8906 /* Get stamp (timeval) */ +-#define SIOCGSTAMPNS_OLD 0x8907 /* Get stamp (timespec) */ ++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + + #endif /* _XTENSA_SOCKIOS_H */ +--- a/include/uapi/asm-generic/sockios.h ++++ b/include/uapi/asm-generic/sockios.h +@@ -8,7 +8,7 @@ + #define FIOGETOWN 0x8903 + #define SIOCGPGRP 0x8904 + #define SIOCATMARK 0x8905 +-#define SIOCGSTAMP_OLD 0x8906 /* Get stamp (timeval) */ +-#define SIOCGSTAMPNS_OLD 0x8907 /* Get stamp (timespec) */ ++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + + #endif /* __ASM_GENERIC_SOCKIOS_H */ +--- a/include/uapi/linux/sockios.h ++++ b/include/uapi/linux/sockios.h +@@ -19,7 +19,6 @@ + #ifndef _LINUX_SOCKIOS_H + #define _LINUX_SOCKIOS_H + +-#include <asm/bitsperlong.h> + #include <asm/sockios.h> + + /* Linux-specific socket ioctls */ +@@ -37,17 +36,6 @@ + /* Get stamp (timespec) */ + #define SIOCGSTAMPNS_NEW _IOR(SOCK_IOC_TYPE, 0x07, long long[2]) + +-#if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__)) +-/* on 64-bit and x32, avoid the ?: operator */ +-#define SIOCGSTAMP SIOCGSTAMP_OLD +-#define SIOCGSTAMPNS SIOCGSTAMPNS_OLD +-#else +-#define SIOCGSTAMP ((sizeof(struct timeval)) == 8 ? \ +- SIOCGSTAMP_OLD : SIOCGSTAMP_NEW) +-#define SIOCGSTAMPNS ((sizeof(struct timespec)) == 8 ? \ +- SIOCGSTAMPNS_OLD : SIOCGSTAMPNS_NEW) +-#endif +- + /* Routing table calls. */ + #define SIOCADDRT 0x890B /* add routing table entry */ + #define SIOCDELRT 0x890C /* delete routing table entry */ +--- a/net/socket.c ++++ b/net/socket.c +@@ -1163,14 +1163,14 @@ static long sock_ioctl(struct file *file + + err = open_related_ns(&net->ns, get_net_ns); + break; +- case SIOCGSTAMP_OLD: +- case SIOCGSTAMPNS_OLD: ++ case SIOCGSTAMP: ++ case SIOCGSTAMPNS: + if (!sock->ops->gettstamp) { + err = -ENOIOCTLCMD; + break; + } + err = sock->ops->gettstamp(sock, argp, +- cmd == SIOCGSTAMP_OLD, ++ cmd == SIOCGSTAMP, + !IS_ENABLED(CONFIG_64BIT)); + break; + case SIOCGSTAMP_NEW: +@@ -3273,11 +3273,11 @@ static int compat_sock_ioctl_trans(struc + case SIOCGIFMAP: + case SIOCSIFMAP: + return compat_sioc_ifmap(net, cmd, argp); +- case SIOCGSTAMP_OLD: +- case SIOCGSTAMPNS_OLD: ++ case SIOCGSTAMP: ++ case SIOCGSTAMPNS: + if (!sock->ops->gettstamp) + return -ENOIOCTLCMD; +- return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD, ++ return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP, + !COMPAT_USE_64BIT_TIME); + + case SIOCETHTOOL: diff --git a/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch new file mode 100644 index 000000000..a40c600ae --- /dev/null +++ b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch @@ -0,0 +1,139 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: radeon, amdgpu: Firmware is required for DRM and KMS on R600 onward +Date: Tue, 08 Jan 2013 03:25:52 +0000 +Bug-Debian: https://bugs.debian.org/607194 +Bug-Debian: https://bugs.debian.org/607471 +Bug-Debian: https://bugs.debian.org/610851 +Bug-Debian: https://bugs.debian.org/627497 +Bug-Debian: https://bugs.debian.org/632212 +Bug-Debian: https://bugs.debian.org/637943 +Bug-Debian: https://bugs.debian.org/649448 +Bug-Debian: https://bugs.debian.org/697229 +Forwarded: no + +radeon requires firmware/microcode for the GPU in all chips, but for +newer chips (apparently R600 'Evergreen' onward) it also expects +firmware for the memory controller and other sub-blocks. + +radeon attempts to gracefully fall back and disable some features if +the firmware is not available, but becomes unstable - the framebuffer +and/or system memory may be corrupted, or the display may stay black. + +Therefore, perform a basic check for the existence of +/lib/firmware/{radeon,amdgpu} when a device is probed, and abort if it +is missing, except for the pre-R600 case. + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 29 ++++++++++++++++++++++++ + drivers/gpu/drm/radeon/radeon_drv.c | 30 +++++++++++++++++++++++++ + 2 files changed, 59 insertions(+) + +Index: debian-kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +=================================================================== +--- debian-kernel.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ debian-kernel/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -36,6 +36,8 @@ + #include <linux/vga_switcheroo.h> + #include <drm/drm_probe_helper.h> + #include <linux/mmu_notifier.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "amdgpu.h" + #include "amdgpu_irq.h" +@@ -1017,6 +1019,28 @@ MODULE_DEVICE_TABLE(pci, pciidlist); + + static struct drm_driver kms_driver; + ++/* Test that /lib/firmware/amdgpu is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool amdgpu_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_AMDGPU) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/amdgpu", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int amdgpu_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +@@ -1070,6 +1094,11 @@ static int amdgpu_pci_probe(struct pci_d + } + #endif + ++ if (!amdgpu_firmware_installed()) { ++ DRM_ERROR("amdgpu requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* Get rid of things like offb */ + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "amdgpudrmfb"); + if (ret) +Index: debian-kernel/drivers/gpu/drm/radeon/radeon_drv.c +=================================================================== +--- debian-kernel.orig/drivers/gpu/drm/radeon/radeon_drv.c ++++ debian-kernel/drivers/gpu/drm/radeon/radeon_drv.c +@@ -48,6 +48,8 @@ + #include <drm/drm_probe_helper.h> + #include <drm/drm_vblank.h> + #include <drm/radeon_drm.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "radeon_drv.h" + +@@ -321,6 +323,28 @@ static struct drm_driver kms_driver; + + bool radeon_device_is_virtual(void); + ++/* Test that /lib/firmware/radeon is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool radeon_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_RADEON) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int radeon_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) + { +@@ -360,6 +384,12 @@ static int radeon_pci_probe(struct pci_d + if (vga_switcheroo_client_probe_defer(pdev)) + return -EPROBE_DEFER; + ++ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 && ++ !radeon_firmware_installed()) { ++ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* Get rid of things like offb */ + ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "radeondrmfb"); + if (ret) diff --git a/debian/patches/bugfix/all/smb3-Replace-smb2pdu-1-element-arrays-with-flex-arra.patch b/debian/patches/bugfix/all/smb3-Replace-smb2pdu-1-element-arrays-with-flex-arra.patch new file mode 100644 index 000000000..bc4e28488 --- /dev/null +++ b/debian/patches/bugfix/all/smb3-Replace-smb2pdu-1-element-arrays-with-flex-arra.patch @@ -0,0 +1,375 @@ +From: Kees Cook <keescook@chromium.org> +Date: Fri, 26 Jan 2024 22:31:43 +0300 +Subject: smb3: Replace smb2pdu 1-element arrays with flex-arrays +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=06aa6eff7b243891c631b40852a0c453e274955d + +commit eb3e28c1e89b4984308777231887e41aa8a0151f upstream. + +The kernel is globally removing the ambiguous 0-length and 1-element +arrays in favor of flexible arrays, so that we can gain both compile-time +and run-time array bounds checking[1]. + +Replace the trailing 1-element array with a flexible array in the +following structures: + + struct smb2_err_rsp + struct smb2_tree_connect_req + struct smb2_negotiate_rsp + struct smb2_sess_setup_req + struct smb2_sess_setup_rsp + struct smb2_read_req + struct smb2_read_rsp + struct smb2_write_req + struct smb2_write_rsp + struct smb2_query_directory_req + struct smb2_query_directory_rsp + struct smb2_set_info_req + struct smb2_change_notify_rsp + struct smb2_create_rsp + struct smb2_query_info_req + struct smb2_query_info_rsp + +Replace the trailing 1-element array with a flexible array, but leave +the existing structure padding: + + struct smb2_file_all_info + struct smb2_lock_req + +Adjust all related size calculations to match the changes to sizeof(). + +No machine code output or .data section differences are produced after +these changes. + +[1] For lots of details, see both: + https://docs.kernel.org/process/deprecated.html#zero-length-and-one-element-arrays + https://people.kernel.org/kees/bounded-flexible-arrays-in-c + +Cc: Steve French <sfrench@samba.org> +Cc: Paulo Alcantara <pc@cjr.nz> +Cc: Ronnie Sahlberg <lsahlber@redhat.com> +Cc: Shyam Prasad N <sprasad@microsoft.com> +Cc: Tom Talpey <tom@talpey.com> +Cc: Namjae Jeon <linkinjeon@kernel.org> +Cc: Sergey Senozhatsky <senozhatsky@chromium.org> +Cc: linux-cifs@vger.kernel.org +Cc: samba-technical@lists.samba.org +Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> +Signed-off-by: Kees Cook <keescook@chromium.org> +Signed-off-by: Steve French <stfrench@microsoft.com> +Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/cifs/smb2misc.c | 2 +- + fs/cifs/smb2ops.c | 14 +++++++------- + fs/cifs/smb2pdu.c | 13 ++++++------- + fs/cifs/smb2pdu.h | 42 ++++++++++++++++++++++++------------------ + 4 files changed, 38 insertions(+), 33 deletions(-) + +diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c +index b98bba887f84..660e00eb4206 100644 +--- a/fs/cifs/smb2misc.c ++++ b/fs/cifs/smb2misc.c +@@ -117,7 +117,7 @@ static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len, + } else if (nc_offset + 1 == non_ctxlen) { + cifs_dbg(FYI, "no SPNEGO security blob in negprot rsp\n"); + size_of_pad_before_neg_ctxts = 0; +- } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE) ++ } else if (non_ctxlen == SMB311_NEGPROT_BASE_SIZE + 1) + /* has padding, but no SPNEGO blob */ + size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen + 1; + else +diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c +index 26edaeb4245d..84850a55c8b7 100644 +--- a/fs/cifs/smb2ops.c ++++ b/fs/cifs/smb2ops.c +@@ -5561,7 +5561,7 @@ struct smb_version_values smb20_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5583,7 +5583,7 @@ struct smb_version_values smb21_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5604,7 +5604,7 @@ struct smb_version_values smb3any_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5625,7 +5625,7 @@ struct smb_version_values smbdefault_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5646,7 +5646,7 @@ struct smb_version_values smb30_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5667,7 +5667,7 @@ struct smb_version_values smb302_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +@@ -5688,7 +5688,7 @@ struct smb_version_values smb311_values = { + .header_size = sizeof(struct smb2_sync_hdr), + .header_preamble_size = 0, + .max_header_size = MAX_SMB2_HDR_SIZE, +- .read_rsp_size = sizeof(struct smb2_read_rsp) - 1, ++ .read_rsp_size = sizeof(struct smb2_read_rsp), + .lock_cmd = SMB2_LOCK, + .cap_unix = 0, + .cap_nt_find = SMB2_NT_FIND, +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 76679dc4e632..4aec01841f0f 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1261,7 +1261,7 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data) + + /* Testing shows that buffer offset must be at location of Buffer[0] */ + req->SecurityBufferOffset = +- cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 1 /* pad */); ++ cpu_to_le16(sizeof(struct smb2_sess_setup_req)); + req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len); + + memset(&rqst, 0, sizeof(struct smb_rqst)); +@@ -1760,8 +1760,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + iov[0].iov_len = total_len - 1; + + /* Testing shows that buffer offset must be at location of Buffer[0] */ +- req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req) +- - 1 /* pad */); ++ req->PathOffset = cpu_to_le16(sizeof(struct smb2_tree_connect_req)); + req->PathLength = cpu_to_le16(unc_path_len - 2); + iov[1].iov_base = unc_path; + iov[1].iov_len = unc_path_len; +@@ -4676,7 +4675,7 @@ int SMB2_query_directory_init(const unsigned int xid, + memcpy(bufptr, &asteriks, len); + + req->FileNameOffset = +- cpu_to_le16(sizeof(struct smb2_query_directory_req) - 1); ++ cpu_to_le16(sizeof(struct smb2_query_directory_req)); + req->FileNameLength = cpu_to_le16(len); + /* + * BB could be 30 bytes or so longer if we used SMB2 specific +@@ -4873,7 +4872,7 @@ SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, + req->AdditionalInformation = cpu_to_le32(additional_info); + + req->BufferOffset = +- cpu_to_le16(sizeof(struct smb2_set_info_req) - 1); ++ cpu_to_le16(sizeof(struct smb2_set_info_req)); + req->BufferLength = cpu_to_le32(*size); + + memcpy(req->Buffer, *data, *size); +@@ -5105,9 +5104,9 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, + req->VolatileFileId = volatile_fid; + /* 1 for pad */ + req->InputBufferOffset = +- cpu_to_le16(sizeof(struct smb2_query_info_req) - 1); ++ cpu_to_le16(sizeof(struct smb2_query_info_req)); + req->OutputBufferLength = cpu_to_le32( +- outbuf_len + sizeof(struct smb2_query_info_rsp) - 1); ++ outbuf_len + sizeof(struct smb2_query_info_rsp)); + + iov->iov_base = (char *)req; + iov->iov_len = total_len; +diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h +index 89a732b31390..eaa873175318 100644 +--- a/fs/cifs/smb2pdu.h ++++ b/fs/cifs/smb2pdu.h +@@ -220,7 +220,7 @@ struct smb2_err_rsp { + __le16 StructureSize; + __le16 Reserved; /* MBZ */ + __le32 ByteCount; /* even if zero, at least one byte follows */ +- __u8 ErrorData[1]; /* variable length */ ++ __u8 ErrorData[]; /* variable length */ + } __packed; + + #define SYMLINK_ERROR_TAG 0x4c4d5953 +@@ -464,7 +464,7 @@ struct smb2_negotiate_rsp { + __le16 SecurityBufferOffset; + __le16 SecurityBufferLength; + __le32 NegotiateContextOffset; /* Pre:SMB3.1.1 was reserved/ignored */ +- __u8 Buffer[1]; /* variable length GSS security buffer */ ++ __u8 Buffer[]; /* variable length GSS security buffer */ + } __packed; + + /* Flags */ +@@ -481,7 +481,7 @@ struct smb2_sess_setup_req { + __le16 SecurityBufferOffset; + __le16 SecurityBufferLength; + __u64 PreviousSessionId; +- __u8 Buffer[1]; /* variable length GSS security buffer */ ++ __u8 Buffer[]; /* variable length GSS security buffer */ + } __packed; + + /* Currently defined SessionFlags */ +@@ -494,7 +494,7 @@ struct smb2_sess_setup_rsp { + __le16 SessionFlags; + __le16 SecurityBufferOffset; + __le16 SecurityBufferLength; +- __u8 Buffer[1]; /* variable length GSS security buffer */ ++ __u8 Buffer[]; /* variable length GSS security buffer */ + } __packed; + + struct smb2_logoff_req { +@@ -520,7 +520,7 @@ struct smb2_tree_connect_req { + __le16 Flags; /* Reserved MBZ for dialects prior to SMB3.1.1 */ + __le16 PathOffset; + __le16 PathLength; +- __u8 Buffer[1]; /* variable length */ ++ __u8 Buffer[]; /* variable length */ + } __packed; + + /* See MS-SMB2 section 2.2.9.2 */ +@@ -828,7 +828,7 @@ struct smb2_create_rsp { + __u64 VolatileFileId; /* opaque endianness */ + __le32 CreateContextsOffset; + __le32 CreateContextsLength; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + struct create_context { +@@ -1289,7 +1289,7 @@ struct smb2_read_plain_req { + __le32 RemainingBytes; + __le16 ReadChannelInfoOffset; + __le16 ReadChannelInfoLength; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + /* Read flags */ +@@ -1304,7 +1304,7 @@ struct smb2_read_rsp { + __le32 DataLength; + __le32 DataRemaining; + __u32 Flags; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + /* For write request Flags field below the following flags are defined: */ +@@ -1324,7 +1324,7 @@ struct smb2_write_req { + __le16 WriteChannelInfoOffset; + __le16 WriteChannelInfoLength; + __le32 Flags; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + struct smb2_write_rsp { +@@ -1335,7 +1335,7 @@ struct smb2_write_rsp { + __le32 DataLength; + __le32 DataRemaining; + __u32 Reserved2; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + /* notify flags */ +@@ -1371,7 +1371,7 @@ struct smb2_change_notify_rsp { + __le16 StructureSize; /* Must be 9 */ + __le16 OutputBufferOffset; + __le32 OutputBufferLength; +- __u8 Buffer[1]; /* array of file notify structs */ ++ __u8 Buffer[]; /* array of file notify structs */ + } __packed; + + #define SMB2_LOCKFLAG_SHARED_LOCK 0x0001 +@@ -1394,7 +1394,10 @@ struct smb2_lock_req { + __u64 PersistentFileId; /* opaque endianness */ + __u64 VolatileFileId; /* opaque endianness */ + /* Followed by at least one */ +- struct smb2_lock_element locks[1]; ++ union { ++ struct smb2_lock_element lock; ++ DECLARE_FLEX_ARRAY(struct smb2_lock_element, locks); ++ }; + } __packed; + + struct smb2_lock_rsp { +@@ -1434,7 +1437,7 @@ struct smb2_query_directory_req { + __le16 FileNameOffset; + __le16 FileNameLength; + __le32 OutputBufferLength; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + struct smb2_query_directory_rsp { +@@ -1442,7 +1445,7 @@ struct smb2_query_directory_rsp { + __le16 StructureSize; /* Must be 9 */ + __le16 OutputBufferOffset; + __le32 OutputBufferLength; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + /* Possible InfoType values */ +@@ -1483,7 +1486,7 @@ struct smb2_query_info_req { + __le32 Flags; + __u64 PersistentFileId; /* opaque endianness */ + __u64 VolatileFileId; /* opaque endianness */ +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + struct smb2_query_info_rsp { +@@ -1491,7 +1494,7 @@ struct smb2_query_info_rsp { + __le16 StructureSize; /* Must be 9 */ + __le16 OutputBufferOffset; + __le32 OutputBufferLength; +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + /* +@@ -1514,7 +1517,7 @@ struct smb2_set_info_req { + __le32 AdditionalInformation; + __u64 PersistentFileId; /* opaque endianness */ + __u64 VolatileFileId; /* opaque endianness */ +- __u8 Buffer[1]; ++ __u8 Buffer[]; + } __packed; + + struct smb2_set_info_rsp { +@@ -1716,7 +1719,10 @@ struct smb2_file_all_info { /* data block encoding of response to level 18 */ + __le32 Mode; + __le32 AlignmentRequirement; + __le32 FileNameLength; +- char FileName[1]; ++ union { ++ char __pad; /* Legacy structure padding */ ++ DECLARE_FLEX_ARRAY(char, FileName); ++ }; + } __packed; /* level 18 Query */ + + struct smb2_file_eof_info { /* encoding of request for level 10 */ +-- +2.43.0 + diff --git a/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch b/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch new file mode 100644 index 000000000..8f8066530 --- /dev/null +++ b/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch @@ -0,0 +1,156 @@ +From: Kees Cook <keescook@chromium.org> +Date: Fri, 26 Jan 2024 22:31:42 +0300 +Subject: stddef: Introduce DECLARE_FLEX_ARRAY() helper +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=ef8316e0e29e98d9cf7e0689ddffa37e79d33736 + +commit 3080ea5553cc909b000d1f1d964a9041962f2c5b upstream. + +There are many places where kernel code wants to have several different +typed trailing flexible arrays. This would normally be done with multiple +flexible arrays in a union, but since GCC and Clang don't (on the surface) +allow this, there have been many open-coded workarounds, usually involving +neighboring 0-element arrays at the end of a structure. For example, +instead of something like this: + +struct thing { + ... + union { + struct type1 foo[]; + struct type2 bar[]; + }; +}; + +code works around the compiler with: + +struct thing { + ... + struct type1 foo[0]; + struct type2 bar[]; +}; + +Another case is when a flexible array is wanted as the single member +within a struct (which itself is usually in a union). For example, this +would be worked around as: + +union many { + ... + struct { + struct type3 baz[0]; + }; +}; + +These kinds of work-arounds cause problems with size checks against such +zero-element arrays (for example when building with -Warray-bounds and +-Wzero-length-bounds, and with the coming FORTIFY_SOURCE improvements), +so they must all be converted to "real" flexible arrays, avoiding warnings +like this: + +fs/hpfs/anode.c: In function 'hpfs_add_sector_to_btree': +fs/hpfs/anode.c:209:27: warning: array subscript 0 is outside the bounds of an interior zero-length array 'struct bplus_internal_node[0]' [-Wzero-length-bounds] + 209 | anode->btree.u.internal[0].down = cpu_to_le32(a); + | ~~~~~~~~~~~~~~~~~~~~~~~^~~ +In file included from fs/hpfs/hpfs_fn.h:26, + from fs/hpfs/anode.c:10: +fs/hpfs/hpfs.h:412:32: note: while referencing 'internal' + 412 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving + | ^~~~~~~~ + +drivers/net/can/usb/etas_es58x/es58x_fd.c: In function 'es58x_fd_tx_can_msg': +drivers/net/can/usb/etas_es58x/es58x_fd.c:360:35: warning: array subscript 65535 is outside the bounds of an interior zero-length array 'u8[0]' {aka 'unsigned char[]'} [-Wzero-length-bounds] + 360 | tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len]; + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from drivers/net/can/usb/etas_es58x/es58x_core.h:22, + from drivers/net/can/usb/etas_es58x/es58x_fd.c:17: +drivers/net/can/usb/etas_es58x/es58x_fd.h:231:6: note: while referencing 'raw_msg' + 231 | u8 raw_msg[0]; + | ^~~~~~~ + +However, it _is_ entirely possible to have one or more flexible arrays +in a struct or union: it just has to be in another struct. And since it +cannot be alone in a struct, such a struct must have at least 1 other +named member -- but that member can be zero sized. Wrap all this nonsense +into the new DECLARE_FLEX_ARRAY() in support of having flexible arrays +in unions (or alone in a struct). + +As with struct_group(), since this is needed in UAPI headers as well, +implement the core there, with a non-UAPI wrapper. + +Additionally update kernel-doc to understand its existence. + +https://github.com/KSPP/linux/issues/137 + +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org> +Signed-off-by: Kees Cook <keescook@chromium.org> +Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/stddef.h | 13 +++++++++++++ + include/uapi/linux/stddef.h | 16 ++++++++++++++++ + scripts/kernel-doc | 3 ++- + 3 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/include/linux/stddef.h b/include/linux/stddef.h +index 938216f8ab7e..31fdbb784c24 100644 +--- a/include/linux/stddef.h ++++ b/include/linux/stddef.h +@@ -84,4 +84,17 @@ enum { + #define struct_group_tagged(TAG, NAME, MEMBERS...) \ + __struct_group(TAG, NAME, /* no attrs */, MEMBERS) + ++/** ++ * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union ++ * ++ * @TYPE: The type of each flexible array element ++ * @NAME: The name of the flexible array member ++ * ++ * In order to have a flexible array member in a union or alone in a ++ * struct, it needs to be wrapped in an anonymous struct with at least 1 ++ * named member, but that member can be empty. ++ */ ++#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ ++ __DECLARE_FLEX_ARRAY(TYPE, NAME) ++ + #endif +diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h +index c3725b492263..7837ba4fe728 100644 +--- a/include/uapi/linux/stddef.h ++++ b/include/uapi/linux/stddef.h +@@ -28,4 +28,20 @@ + struct { MEMBERS } ATTRS; \ + struct TAG { MEMBERS } ATTRS NAME; \ + } ++ ++/** ++ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union ++ * ++ * @TYPE: The type of each flexible array element ++ * @NAME: The name of the flexible array member ++ * ++ * In order to have a flexible array member in a union or alone in a ++ * struct, it needs to be wrapped in an anonymous struct with at least 1 ++ * named member, but that member can be empty. ++ */ ++#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ ++ struct { \ ++ struct { } __empty_ ## NAME; \ ++ TYPE NAME[]; \ ++ } + #endif +diff --git a/scripts/kernel-doc b/scripts/kernel-doc +index 19af6dd160e6..7a04d4c05326 100755 +--- a/scripts/kernel-doc ++++ b/scripts/kernel-doc +@@ -1232,7 +1232,8 @@ sub dump_struct($$) { + $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; +- ++ # replace DECLARE_FLEX_ARRAY ++ $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos; + my $declaration = $members; + + # Split nested struct/union elements as newer ones +-- +2.43.0 + diff --git a/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch new file mode 100644 index 000000000..3818dbb17 --- /dev/null +++ b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch @@ -0,0 +1,27 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 21 Feb 2016 15:33:15 +0000 +Subject: tools/build: Remove bpf() run-time check at build time +Forwarded: no + +It is not correct to test that a syscall works on the build system's +kernel. We might be building on an earlier kernel version or with +security restrictions that block bpf(). + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/tools/build/feature/test-bpf.c ++++ b/tools/build/feature/test-bpf.c +@@ -35,8 +35,10 @@ int main(void) + attr.prog_flags = 0; + + /* +- * Test existence of __NR_bpf and BPF_PROG_LOAD. +- * This call should fail if we run the testcase. ++ * bwh: Don't use the bpf() syscall as we might be building on a ++ * much older kernel. Do "use" the attr structure here to avoid ++ * a "set but not used" warning. + */ +- return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); ++ (void)&attr; ++ return 0; + } diff --git a/debian/patches/bugfix/all/tools-perf-man-date.patch b/debian/patches/bugfix/all/tools-perf-man-date.patch new file mode 100644 index 000000000..80a19b554 --- /dev/null +++ b/debian/patches/bugfix/all/tools-perf-man-date.patch @@ -0,0 +1,44 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 13 Jul 2015 20:29:20 +0100 +Subject: perf tools: Use $KBUILD_BUILD_TIMESTAMP as man page date +Forwarded: http://mid.gmane.org/20160517132809.GE7555@decadent.org.uk + +This allows man pages to be built reproducibly. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/perf/Documentation/Makefile | 3 +++ + tools/perf/Documentation/asciidoc.conf | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile +index adc5a7e44b98..2161b2e838b7 100644 +--- a/tools/perf/Documentation/Makefile ++++ b/tools/perf/Documentation/Makefile +@@ -132,6 +132,9 @@ endif + ifdef DOCBOOK_SUPPRESS_SP + XMLTO_EXTRA += -m manpage-suppress-sp.xsl + endif ++ifdef KBUILD_BUILD_TIMESTAMP ++ASCIIDOC_EXTRA += -a revdate=$(shell date -u -d '$(KBUILD_BUILD_TIMESTAMP)' +%Y-%m-%d) ++endif + + SHELL_PATH ?= $(SHELL) + # Shell quote; +diff --git a/tools/perf/Documentation/asciidoc.conf b/tools/perf/Documentation/asciidoc.conf +index 2b62ba1e72b7..82d3060177ba 100644 +--- a/tools/perf/Documentation/asciidoc.conf ++++ b/tools/perf/Documentation/asciidoc.conf +@@ -71,6 +71,9 @@ ifdef::backend-docbook[] + [header] + template::[header-declarations] + <refentry> ++<refentryinfo> ++template::[docinfo] ++</refentryinfo> + ifdef::perf_date[] + <refentryinfo><date>{perf_date}</date></refentryinfo> + endif::perf_date[] +-- +2.23.0 + diff --git a/debian/patches/bugfix/all/tools-perf-pmu-events-fix-reproducibility.patch b/debian/patches/bugfix/all/tools-perf-pmu-events-fix-reproducibility.patch new file mode 100644 index 000000000..6da31fcd3 --- /dev/null +++ b/debian/patches/bugfix/all/tools-perf-pmu-events-fix-reproducibility.patch @@ -0,0 +1,175 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 25 Aug 2019 13:49:41 +0100 +Subject: tools/perf: pmu-events: Fix reproducibility +Forwarded: https://lore.kernel.org/lkml/20190825131329.naqzd5kwg7mw5d3f@decadent.org.uk/T/#u + +jevents.c uses nftw() to enumerate files and outputs the corresponding +C structs in the order they are found. This makes it sensitive to +directory ordering, so that the perf executable is not reproducible. + +To avoid this, store all the files and directories found and then sort +them by their (relative) path. (This maintains the parent-first +ordering that nftw() promises.) Then apply the existing callbacks to +them in the sorted order. + +Don't both storing the stat buffers as we don't need them. + +References: https://tests.reproducible-builds.org/debian/dbdtxt/bullseye/i386/linux_4.19.37-6.diffoscope.txt.gz +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/tools/perf/pmu-events/jevents.c ++++ b/tools/perf/pmu-events/jevents.c +@@ -50,6 +50,18 @@ + #include "json.h" + #include "pmu-events.h" + ++struct ordered_ftw_entry { ++ const char *fpath; ++ int typeflag; ++ struct FTW ftwbuf; ++}; ++ ++struct ordered_ftw_state { ++ struct ordered_ftw_entry *entries; ++ size_t n; ++ size_t max; ++}; ++ + int verbose; + char *prog; + +@@ -905,6 +917,78 @@ static int get_maxfds(void) + */ + static FILE *eventsfp; + static char *mapfile; ++static struct ordered_ftw_state *ordered_ftw_state; ++ ++static int ordered_ftw_add(const char *fpath, const struct stat *sb, ++ int typeflag, struct FTW *ftwbuf) ++{ ++ struct ordered_ftw_state *state = ordered_ftw_state; ++ struct ordered_ftw_entry *entry; ++ ++ if (ftwbuf->level == 0 || ftwbuf->level > 3) ++ return 0; ++ ++ /* Grow array if necessary */ ++ if (state->n >= state->max) { ++ if (state->max == 0) ++ state->max = 16; ++ else ++ state->max *= 2; ++ state->entries = realloc(state->entries, ++ state->max * sizeof(*state->entries)); ++ } ++ ++ entry = &state->entries[state->n++]; ++ entry->fpath = strdup(fpath); ++ entry->typeflag = typeflag; ++ entry->ftwbuf = *ftwbuf; ++ ++ return 0; ++} ++ ++static int ordered_ftw_compare(const void *left, const void *right) ++{ ++ const struct ordered_ftw_entry *left_entry = left; ++ const struct ordered_ftw_entry *right_entry = right; ++ ++ return strcmp(left_entry->fpath, right_entry->fpath); ++} ++ ++/* ++ * Wrapper for nftw() that iterates files in ASCII-order to ensure ++ * reproducible output ++ */ ++static int ordered_ftw(const char *dirpath, ++ int (*fn)(const char *, int, struct FTW *), ++ int nopenfd) ++{ ++ struct ordered_ftw_state state = { NULL, 0, 0 }; ++ size_t i; ++ int rc; ++ ++ ordered_ftw_state = &state; ++ rc = nftw(dirpath, ordered_ftw_add, nopenfd, 0); ++ if (rc) ++ goto out; ++ ++ qsort(state.entries, state.n, sizeof(*state.entries), ++ ordered_ftw_compare); ++ ++ for (i = 0; i < state.n; i++) { ++ rc = fn(state.entries[i].fpath, ++ state.entries[i].typeflag, ++ &state.entries[i].ftwbuf); ++ if (rc) ++ goto out; ++ } ++ ++out: ++ for (i = 0; i < state.n; i++) ++ free((char *)state.entries[i].fpath); ++ free(state.entries);; ++ ++ return rc; ++} + + static int is_leaf_dir(const char *fpath) + { +@@ -957,19 +1041,19 @@ static int is_json_file(const char *name + return 0; + } + +-static int preprocess_arch_std_files(const char *fpath, const struct stat *sb, ++static int preprocess_arch_std_files(const char *fpath, + int typeflag, struct FTW *ftwbuf) + { + int level = ftwbuf->level; + int is_file = typeflag == FTW_F; + + if (level == 1 && is_file && is_json_file(fpath)) +- return json_events(fpath, save_arch_std_events, (void *)sb); ++ return json_events(fpath, save_arch_std_events, NULL); + + return 0; + } + +-static int process_one_file(const char *fpath, const struct stat *sb, ++static int process_one_file(const char *fpath, + int typeflag, struct FTW *ftwbuf) + { + char *tblname, *bname; +@@ -994,9 +1078,9 @@ static int process_one_file(const char * + } else + bname = (char *) fpath + ftwbuf->base; + +- pr_debug("%s %d %7jd %-20s %s\n", ++ pr_debug("%s %d %-20s %s\n", + is_file ? "f" : is_dir ? "d" : "x", +- level, sb->st_size, bname, fpath); ++ level, bname, fpath); + + /* base dir or too deep */ + if (level == 0 || level > 3) +@@ -1152,17 +1236,17 @@ int main(int argc, char *argv[]) + */ + + maxfds = get_maxfds(); +- rc = nftw(ldirname, preprocess_arch_std_files, maxfds, 0); ++ rc = ordered_ftw(ldirname, preprocess_arch_std_files, maxfds); + if (rc) + goto err_processing_std_arch_event_dir; + +- rc = nftw(ldirname, process_one_file, maxfds, 0); ++ rc = ordered_ftw(ldirname, process_one_file, maxfds); + if (rc) + goto err_processing_dir; + + sprintf(ldirname, "%s/test", start_dirname); + +- rc = nftw(ldirname, process_one_file, maxfds, 0); ++ rc = ordered_ftw(ldirname, process_one_file, maxfds); + if (rc) + goto err_processing_dir; + diff --git a/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch new file mode 100644 index 000000000..9766e0e4a --- /dev/null +++ b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch @@ -0,0 +1,39 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Sep 2015 20:09:23 +0100 +Subject: tools/perf: Remove shebang lines from perf scripts +Forwarded: no + +perf scripts need to be invoked through perf, not directly through +perl (or other language interpreter). So including shebang lines in +them is useless and possibly misleading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/tools/perf/scripts/perl/rw-by-file.pl ++++ b/tools/perf/scripts/perl/rw-by-file.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # SPDX-License-Identifier: GPL-2.0-only + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + +--- a/tools/perf/scripts/perl/rw-by-pid.pl ++++ b/tools/perf/scripts/perl/rw-by-pid.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # SPDX-License-Identifier: GPL-2.0-only + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + +--- a/tools/perf/scripts/perl/rwtop.pl ++++ b/tools/perf/scripts/perl/rwtop.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # SPDX-License-Identifier: GPL-2.0-only + # (c) 2010, Tom Zanussi <tzanussi@gmail.com> + +--- a/tools/perf/scripts/perl/wakeup-latency.pl ++++ b/tools/perf/scripts/perl/wakeup-latency.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # SPDX-License-Identifier: GPL-2.0-only + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + diff --git a/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch new file mode 100644 index 000000000..d9d7b301d --- /dev/null +++ b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 24 Jun 2012 02:51:39 +0100 +Subject: usbip: Document TCP wrappers +Forwarded: no + +Add references to TCP wrappers configuration in the manual page. + +--- a/tools/usb/usbip/doc/usbipd.8 ++++ b/tools/usb/usbip/doc/usbipd.8 +@@ -14,7 +14,8 @@ Devices have to explicitly be exported u + before usbipd makes them available to other hosts. + + The daemon accepts connections from USB/IP clients +-on TCP port 3240 by default. ++on TCP port 3240 by default. The clients authorised to connect may be ++configured as documented in hosts_access(5). + + .SH OPTIONS + .HP +@@ -69,7 +70,8 @@ Show version. + + .B usbipd + offers no authentication or authorization for USB/IP. Any +-USB/IP client can connect and use exported devices. ++USB/IP client running on an authorised host can connect and ++use exported devices. + + .SH EXAMPLES + diff --git a/debian/patches/bugfix/all/vfs-move-cap_convert_nscap-call-into-vfs_setxattr.patch b/debian/patches/bugfix/all/vfs-move-cap_convert_nscap-call-into-vfs_setxattr.patch new file mode 100644 index 000000000..d6f698251 --- /dev/null +++ b/debian/patches/bugfix/all/vfs-move-cap_convert_nscap-call-into-vfs_setxattr.patch @@ -0,0 +1,100 @@ +From: Miklos Szeredi <mszeredi@redhat.com> +Date: Mon, 14 Dec 2020 15:26:13 +0100 +Subject: vfs: move cap_convert_nscap() call into vfs_setxattr() +Origin: https://git.kernel.org/linus/7c03e2cda4a584cadc398e8f6641ca9988a39d52 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-3493 + +cap_convert_nscap() does permission checking as well as conversion of the +xattr value conditionally based on fs's user-ns. + +This is needed by overlayfs and probably other layered fs (ecryptfs) and is +what vfs_foo() is supposed to do anyway. + +Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> +Acked-by: James Morris <jamorris@linux.microsoft.com> +--- + fs/xattr.c | 17 +++++++++++------ + include/linux/capability.h | 2 +- + security/commoncap.c | 3 +-- + 3 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/fs/xattr.c b/fs/xattr.c +index cd7a563e8bcd..fd57153b1f61 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -276,8 +276,16 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, + { + struct inode *inode = dentry->d_inode; + struct inode *delegated_inode = NULL; ++ const void *orig_value = value; + int error; + ++ if (size && strcmp(name, XATTR_NAME_CAPS) == 0) { ++ error = cap_convert_nscap(dentry, &value, size); ++ if (error < 0) ++ return error; ++ size = error; ++ } ++ + retry_deleg: + inode_lock(inode); + error = __vfs_setxattr_locked(dentry, name, value, size, flags, +@@ -289,6 +297,9 @@ vfs_setxattr(struct dentry *dentry, const char *name, const void *value, + if (!error) + goto retry_deleg; + } ++ if (value != orig_value) ++ kfree(value); ++ + return error; + } + EXPORT_SYMBOL_GPL(vfs_setxattr); +@@ -537,12 +548,6 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, + if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || + (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) + posix_acl_fix_xattr_from_user(kvalue, size); +- else if (strcmp(kname, XATTR_NAME_CAPS) == 0) { +- error = cap_convert_nscap(d, &kvalue, size); +- if (error < 0) +- goto out; +- size = error; +- } + } + + error = vfs_setxattr(d, kname, kvalue, size, flags); +diff --git a/include/linux/capability.h b/include/linux/capability.h +index 1e7fe311cabe..b2f698915c0f 100644 +--- a/include/linux/capability.h ++++ b/include/linux/capability.h +@@ -270,6 +270,6 @@ static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns) + /* audit system wants to get cap info from files as well */ + extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); + +-extern int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size); ++extern int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size); + + #endif /* !_LINUX_CAPABILITY_H */ +diff --git a/security/commoncap.c b/security/commoncap.c +index 59bf3c1674c8..bacc1111d871 100644 +--- a/security/commoncap.c ++++ b/security/commoncap.c +@@ -473,7 +473,7 @@ static bool validheader(size_t size, const struct vfs_cap_data *cap) + * + * If all is ok, we return the new size, on error return < 0. + */ +-int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) ++int cap_convert_nscap(struct dentry *dentry, const void **ivalue, size_t size) + { + struct vfs_ns_cap_data *nscap; + uid_t nsrootid; +@@ -516,7 +516,6 @@ int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) + nscap->magic_etc = cpu_to_le32(nsmagic); + memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + +- kvfree(*ivalue); + *ivalue = nscap; + return newsize; + } +-- +2.31.0 + diff --git a/debian/patches/bugfix/all/wireguard-ignore-config_android.patch b/debian/patches/bugfix/all/wireguard-ignore-config_android.patch new file mode 100644 index 000000000..5ff53c0b7 --- /dev/null +++ b/debian/patches/bugfix/all/wireguard-ignore-config_android.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <benh@debian.org> +Date: Thu, 07 Jul 2022 18:58:43 +0200 +Subject: wireguard: Clear keys after suspend despite CONFIG_ANDROID=y +Forwarded: not-needed + +WireGuard assumes that CONFIG_ANDROID implies Android power +management, i.e. user-space suspending the system automatically at +short intervals, and so does not clear keys after a suspend/resume +cycle. Debian systems don't do that kind of power management but we +do set CONFIG_ANDROID on some architectures as a dependency of Binder. + +In 5.20, CONFIG_PM_USERSPACE_AUTOSLEEP will be introduced to tell the +kernel that this kind of power management is in use, and +CONFIG_ANDROID will be removed. For now, remove this one test that +does the wrong thing for us. + +References: https://lwn.net/Articles/899743/ +--- +--- a/drivers/net/wireguard/device.c ++++ b/drivers/net/wireguard/device.c +@@ -71,7 +71,7 @@ static int wg_pm_notification(struct not + * its normal operation rather than as a somewhat rare event, then we + * don't actually want to clear keys. + */ +- if (IS_ENABLED(CONFIG_PM_AUTOSLEEP) || IS_ENABLED(CONFIG_ANDROID)) ++ if (IS_ENABLED(CONFIG_PM_AUTOSLEEP)) + return 0; + + if (action != PM_HIBERNATION_PREPARE && action != PM_SUSPEND_PREPARE) diff --git a/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch new file mode 100644 index 000000000..9e6622fb0 --- /dev/null +++ b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch @@ -0,0 +1,37 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 17 Feb 2017 01:30:30 +0000 +Subject: ARM: dts: kirkwood: Fix SATA pinmux-ing for TS419 +Forwarded: https://www.spinics.net/lists/arm-kernel/msg563610.html +Bug-Debian: https://bugs.debian.org/855017 + +The old board code for the TS419 assigns MPP pins 15 and 16 as SATA +activity signals (and none as SATA presence signals). Currently the +device tree assigns the SoC's default pinmux groups for SATA, which +conflict with the second Ethernet port. + +Reported-by: gmbh@gazeta.pl +Tested-by: gmbh@gazeta.pl +References: https://bugs.debian.org/855017 +Cc: stable@vger.kernel.org # 3.15+ +Fixes: 934b524b3f49 ("ARM: Kirkwood: Add DT description of QNAP 419") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/boot/dts/kirkwood-ts419.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/kirkwood-ts419.dtsi b/arch/arm/boot/dts/kirkwood-ts419.dtsi +index 02bd53762705..532506cb0f4a 100644 +--- a/arch/arm/boot/dts/kirkwood-ts419.dtsi ++++ b/arch/arm/boot/dts/kirkwood-ts419.dtsi +@@ -73,3 +73,11 @@ + phy-handle = <ðphy1>; + }; + }; ++ ++&pmx_sata0 { ++ marvell,pins = "mpp15"; ++}; ++ ++&pmx_sata1 { ++ marvell,pins = "mpp16"; ++}; diff --git a/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch new file mode 100644 index 000000000..1bdd37fbe --- /dev/null +++ b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 11 Jul 2018 23:40:55 +0100 +Subject: ARM: mm: Export __sync_icache_dcache() for xen-privcmd +Forwarded: https://marc.info/?l=linux-arm-kernel&m=153134944429241 + +The xen-privcmd driver, which can be modular, calls set_pte_at() +which in turn may call __sync_icache_dcache(). + +The call to __sync_icache_dcache() may be optimised out because it is +conditional on !pte_special(), and xen-privcmd calls pte_mkspecial(). +However, in a non-LPAE configuration there is no "special" bit and the +call is really unconditional. + +Fixes: 3ad0876554ca ("xen/privcmd: add IOCTL_PRIVCMD_MMAP_RESOURCE") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/mm/flush.c | 1 + + 1 file changed, 1 insertion(+) + +Index: debian-kernel/arch/arm/mm/flush.c +=================================================================== +--- debian-kernel.orig/arch/arm/mm/flush.c ++++ debian-kernel/arch/arm/mm/flush.c +@@ -292,6 +292,7 @@ void __sync_icache_dcache(pte_t pteval) + if (pte_exec(pteval)) + __flush_icache_all(); + } ++EXPORT_SYMBOL_GPL(__sync_icache_dcache); + #endif + + /* diff --git a/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch new file mode 100644 index 000000000..b3b031668 --- /dev/null +++ b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch @@ -0,0 +1,92 @@ +From: Geoff Levand <geoff@infradead.org> +Date: Wed, 13 Jun 2018 10:56:08 -0700 +Subject: arm64/acpi: Add fixup for HPE m400 quirks +Forwarded: https://patchwork.codeaurora.org/patch/547277/ + +Adds a new ACPI init routine acpi_fixup_m400_quirks that adds +a work-around for HPE ProLiant m400 APEI firmware problems. + +The work-around disables APEI when CONFIG_ACPI_APEI is set and +m400 firmware is detected. Without this fixup m400 systems +experience errors like these on startup: + + [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2 + [Hardware Error]: event severity: fatal + [Hardware Error]: Error 0, type: fatal + [Hardware Error]: section_type: memory error + [Hardware Error]: error_status: 0x0000000000001300 + [Hardware Error]: error_type: 10, invalid address + Kernel panic - not syncing: Fatal hardware error! + +Signed-off-by: Geoff Levand <geoff@infradead.org> +[bwh: Adjust context to apply to Linux 4.19] +--- + arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 36 insertions(+), 4 deletions(-) + +Index: debian-kernel/arch/arm64/kernel/acpi.c +=================================================================== +--- debian-kernel.orig/arch/arm64/kernel/acpi.c ++++ debian-kernel/arch/arm64/kernel/acpi.c +@@ -32,6 +32,8 @@ + #include <asm/daifflags.h> + #include <asm/smp_plat.h> + ++#include <acpi/apei.h> ++ + int acpi_noirq = 1; /* skip ACPI IRQ initialization */ + int acpi_disabled = 1; + EXPORT_SYMBOL(acpi_disabled); +@@ -178,6 +180,33 @@ out: + } + + /* ++ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware ++ * problems. ++ */ ++static void __init acpi_fixup_m400_quirks(void) ++{ ++ acpi_status status; ++ struct acpi_table_header *header; ++#if !defined(CONFIG_ACPI_APEI) ++ int hest_disable = HEST_DISABLED; ++#endif ++ ++ if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED) ++ return; ++ ++ status = acpi_get_table(ACPI_SIG_HEST, 0, &header); ++ ++ if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE ", 6) && ++ !strncmp(header->oem_table_id, "ProLiant", 8) && ++ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) { ++ hest_disable = HEST_DISABLED; ++ pr_info("Disabled APEI for m400.\n"); ++ } ++ ++ acpi_put_table(header); ++} ++ ++/* + * acpi_boot_table_init() called from setup_arch(), always. + * 1. find RSDP and get its address, and then find XSDT + * 2. extract all tables and checksums them all +@@ -232,11 +261,14 @@ done: + if (acpi_disabled) { + if (earlycon_acpi_spcr_enable) + early_init_dt_scan_chosen_stdout(); +- } else { +- acpi_parse_spcr(earlycon_acpi_spcr_enable, true); +- if (IS_ENABLED(CONFIG_ACPI_BGRT)) +- acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); ++ return; + } ++ ++ acpi_parse_spcr(earlycon_acpi_spcr_enable, true); ++ if (IS_ENABLED(CONFIG_ACPI_BGRT)) ++ acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); ++ ++ acpi_fixup_m400_quirks(); + } + + pgprot_t __acpi_get_mem_attribute(phys_addr_t addr) diff --git a/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch new file mode 100644 index 000000000..2d568d35e --- /dev/null +++ b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch @@ -0,0 +1,45 @@ +From: Heinrich Schuchardt <xypron.glpk@gmx.de> +Date: Mon, 4 Jun 2018 19:15:23 +0200 +Subject: arm64: dts: rockchip: correct voltage selector on Firefly-RK3399 +Bug-Debian: https://bugs.debian.org/900799 +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=710e8c4a54be82ee8a97324e7b4330bf191e08bf + +Without this patch the Firefly-RK3399 board boot process hangs after these +lines: + + fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected! + fan53555-reg: supplied by vcc_sys + vcc1v8_s3: supplied by vcc_1v8 + +Blacklisting driver fan53555 allows booting. + +The device tree uses a value of fcs,suspend-voltage-selector different to +any other board. + +Changing this setting to the usual value is sufficient to enable booting +and also matches the value used in the vendor kernel. + +Fixes: 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board") +Cc: stable@vger.kernel.org +Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +index 86ff1eb..d8a2f0b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -421,7 +421,7 @@ + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; +- fcs,suspend-voltage-selector = <0>; ++ fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; +-- +cgit v1.1 + diff --git a/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch new file mode 100644 index 000000000..0b3acfadb --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch @@ -0,0 +1,39 @@ +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Wed, 29 Aug 2018 09:32:23 +0200 +Subject: powerpc/boot: Fix missing crc32poly.h when building with KERNEL_XZ +Origin: https://patchwork.ozlabs.org/patch/963258/ + +After commit faa16bc404d7 ("lib: Use existing define with +polynomial") the lib/xz/xz_crc32.c includes a header from include/linux +directory thus any other user of this code should define proper include +path. + +This fixes the build error on powerpc with CONFIG_KERNEL_XZ: + + In file included from ../arch/powerpc/boot/../../../lib/decompress_unxz.c:233:0, + from ../arch/powerpc/boot/decompress.c:42: + ../arch/powerpc/boot/../../../lib/xz/xz_crc32.c:18:29: fatal error: linux/crc32poly.h: No such file or directory + +Reported-by: Michal Kubecek <mkubecek@suse.cz> +Fixes: faa16bc404d7 ("lib: Use existing define with polynomial") +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Reported-by: kbuild test robot <lkp@intel.com> +Reported-by: Meelis Roos <mroos@linux.ee> +Tested-by: Michal Kubecek <mkubecek@suse.cz> +--- + arch/powerpc/boot/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile +index 0fb96c26136f..ba4182fb185d 100644 +--- a/arch/powerpc/boot/Makefile ++++ b/arch/powerpc/boot/Makefile +@@ -63,7 +63,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y) + BOOTCFLAGS += -fno-stack-protector + endif + +-BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) ++BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) -I$(srctree)/include + + DTC_FLAGS ?= -p 1024 + diff --git a/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch new file mode 100644 index 000000000..25e5b1044 --- /dev/null +++ b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch @@ -0,0 +1,124 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 19 Aug 2017 21:42:09 +0100 +Subject: sh: Do not use hyphen in exported variable names +Forwarded: https://marc.info/?l=linux-sh&m=150317827322995&w=2 + +arch/sh/Makefile defines and exports ld-bfd to be used by +arch/sh/boot/Makefile and arch/sh/boot/compressed/Makefile. Similarly +arch/sh/boot/Makefile defines and exports suffix-y to be used by +arch/sh/boot/compressed/Makefile. However some shells, including +dash, will not pass through environment variables whose name includes +a hyphen. Usually GNU make does not use a shell to recurse, but if +e.g. $(srctree) contains '~' it will use a shell here. + +Rename these variables to ld_bfd and suffix_y. + +References: https://buildd.debian.org/status/fetch.php?pkg=linux&arch=sh4&ver=4.13%7Erc5-1%7Eexp1&stamp=1502943967&raw=0 +Fixes: ef9b542fce00 ("sh: bzip2/lzma uImage support.") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/sh/Makefile | 10 +++++----- + arch/sh/boot/Makefile | 16 ++++++++-------- + arch/sh/boot/compressed/Makefile | 6 +++--- + arch/sh/boot/romimage/Makefile | 4 ++-- + 4 files changed, 18 insertions(+), 18 deletions(-) + +--- a/arch/sh/Makefile ++++ b/arch/sh/Makefile +@@ -102,16 +102,16 @@ UTS_MACHINE := sh + LDFLAGS_vmlinux += -e _stext + + ifdef CONFIG_CPU_LITTLE_ENDIAN +-ld-bfd := elf32-sh-linux +-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd) ++ld_bfd := elf32-sh-linux ++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld_bfd) + KBUILD_LDFLAGS += -EL + else +-ld-bfd := elf32-shbig-linux +-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd) ++ld_bfd := elf32-shbig-linux ++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld_bfd) + KBUILD_LDFLAGS += -EB + endif + +-export ld-bfd ++export ld_bfd + + head-y := arch/sh/kernel/head_32.o + +--- a/arch/sh/boot/Makefile ++++ b/arch/sh/boot/Makefile +@@ -19,12 +19,12 @@ CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 + CONFIG_ENTRY_OFFSET ?= 0x00001000 + CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START) + +-suffix-y := bin +-suffix-$(CONFIG_KERNEL_GZIP) := gz +-suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +-suffix-$(CONFIG_KERNEL_LZMA) := lzma +-suffix-$(CONFIG_KERNEL_XZ) := xz +-suffix-$(CONFIG_KERNEL_LZO) := lzo ++suffix_y := bin ++suffix_$(CONFIG_KERNEL_GZIP) := gz ++suffix_$(CONFIG_KERNEL_BZIP2) := bz2 ++suffix_$(CONFIG_KERNEL_LZMA) := lzma ++suffix_$(CONFIG_KERNEL_XZ) := xz ++suffix_$(CONFIG_KERNEL_LZO) := lzo + + targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \ + uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin +@@ -106,10 +106,10 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O + $(obj)/uImage.srec: $(obj)/uImage + $(call if_changed,objcopy) + +-$(obj)/uImage: $(obj)/uImage.$(suffix-y) ++$(obj)/uImage: $(obj)/uImage.$(suffix_y) + @ln -sf $(notdir $<) $@ + @echo ' Image $@ is ready' + + export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ + CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \ +- KERNEL_MEMORY suffix-y ++ KERNEL_MEMORY suffix_y +--- a/arch/sh/boot/compressed/Makefile ++++ b/arch/sh/boot/compressed/Makefile +@@ -30,7 +30,7 @@ endif + + ccflags-remove-$(CONFIG_MCOUNT) += -pg + +-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \ ++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(IMAGE_OFFSET) -e startup \ + -T $(obj)/../../kernel/vmlinux.lds + + # +@@ -68,7 +68,7 @@ $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.al + + OBJCOPYFLAGS += -R .empty_zero_page + +-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T ++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T + +-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE ++$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE + $(call if_changed,ld) +--- a/arch/sh/boot/romimage/Makefile ++++ b/arch/sh/boot/romimage/Makefile +@@ -13,7 +13,7 @@ mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) : + load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y) + obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y) + +-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \ ++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(load-y) -e romstart \ + -T $(obj)/../../kernel/vmlinux.lds + + $(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE +@@ -24,7 +24,7 @@ OBJCOPYFLAGS += -j .empty_zero_page + $(obj)/zeropage.bin: vmlinux FORCE + $(call if_changed,objcopy) + +-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T ++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T + + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE + $(call if_changed,ld) diff --git a/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch new file mode 100644 index 000000000..f9baa7bd3 --- /dev/null +++ b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch @@ -0,0 +1,35 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 22 Jul 2017 17:37:33 +0100 +Subject: perf tools: Fix unwind build on i386 +Forwarded: no + +EINVAL may not be defined when building unwind-libunwind.c with +REMOTE_UNWIND_LIBUNWIND, resulting in a compiler error in +LIBUNWIND__ARCH_REG_ID(). Its only caller, access_reg(), only checks +for a negative return value and doesn't care what it is. So change +-EINVAL to -1. + +Fixes: 52ffe0ff02fc ("Support x86(32-bit) cross platform callchain unwind.") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + +--- a/tools/perf/arch/x86/util/unwind-libunwind.c ++++ b/tools/perf/arch/x86/util/unwind-libunwind.c +@@ -66,7 +66,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum) + break; + default: + pr_err("unwind: invalid reg id %d\n", regnum); +- return -EINVAL; ++ return -1; + } + + return id; +@@ -106,7 +106,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum) + break; + default: + pr_err("unwind: invalid reg id %d\n", regnum); +- return -EINVAL; ++ return -1; + } + + return id; diff --git a/debian/patches/bugfix/x86/platform-x86-toshiba_haps-Fix-missing-newline-in-pr_.patch b/debian/patches/bugfix/x86/platform-x86-toshiba_haps-Fix-missing-newline-in-pr_.patch new file mode 100644 index 000000000..73d28aeb6 --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-toshiba_haps-Fix-missing-newline-in-pr_.patch @@ -0,0 +1,34 @@ +From: Hans de Goede <hdegoede@redhat.com> +Date: Wed, 19 May 2021 15:56:18 +0200 +Subject: platform/x86: toshiba_haps: Fix missing newline in pr_debug call in + toshiba_haps_notify +Origin: https://git.kernel.org/linus/7dc4a18d017ca26abd1cea197e486fb3e5cd7632 +Bug-Debian: https://bugs.debian.org/799193 + +The pr_debug() call in toshiba_haps_notify() is missing a newline at the +end of the string, add this. + +BugLink: https://bugs.debian.org/799193 +Reported-by: Salvatore Bonaccorso <carnil@debian.org> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Link: https://lore.kernel.org/r/20210519135618.139701-1-hdegoede@redhat.com +--- + drivers/platform/x86/toshiba_haps.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/platform/x86/toshiba_haps.c b/drivers/platform/x86/toshiba_haps.c +index b237bd6b1ee5..49e84095bb01 100644 +--- a/drivers/platform/x86/toshiba_haps.c ++++ b/drivers/platform/x86/toshiba_haps.c +@@ -131,7 +131,7 @@ static const struct attribute_group haps_attr_group = { + */ + static void toshiba_haps_notify(struct acpi_device *device, u32 event) + { +- pr_debug("Received event: 0x%x", event); ++ pr_debug("Received event: 0x%x\n", event); + + acpi_bus_generate_netlink_event(device->pnp.device_class, + dev_name(&device->dev), +-- +2.32.0 + diff --git a/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch new file mode 100644 index 000000000..cfbf98e82 --- /dev/null +++ b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch @@ -0,0 +1,22 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Sep 2015 22:50:50 +0100 +Subject: Revert "perf build: Fix libunwind feature detection on 32-bit x86" +Forwarded: no + +This reverts commit 05b41775e2edd69a83f592e3534930c934d4038e. +It broke feature detection that was working just fine for us. +--- + tools/perf/Makefile.config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/perf/Makefile.config ++++ b/tools/perf/Makefile.config +@@ -38,7 +38,7 @@ ifeq ($(SRCARCH),x86) + LIBUNWIND_LIBS = -lunwind-x86_64 -lunwind -llzma + $(call detected,CONFIG_X86_64) + else +- LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind ++ LIBUNWIND_LIBS = -lunwind -lunwind-x86 + endif + NO_PERF_REGS := 0 + endif diff --git a/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch new file mode 100644 index 000000000..62b4eb7de --- /dev/null +++ b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch @@ -0,0 +1,34 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 20 Apr 2013 15:52:02 +0100 +Subject: viafb: Autoload on OLPC XO 1.5 only +Bug-Debian: https://bugs.debian.org/705788 +Forwarded: no + +It appears that viafb won't work automatically on all the boards for +which it has a PCI device ID match. Currently, it is blacklisted by +udev along with most other framebuffer drivers, so this doesn't matter +much. + +However, this driver is required for console support on the XO 1.5. +We need to allow it to be autoloaded on this model only, and then +un-blacklist it in udev. + +--- +--- a/drivers/video/fbdev/via/via-core.c ++++ b/drivers/video/fbdev/via/via-core.c +@@ -695,7 +695,14 @@ static const struct pci_device_id via_pc + .driver_data = UNICHROME_VX900 }, + { } + }; +-MODULE_DEVICE_TABLE(pci, via_pci_table); ++ ++static const struct pci_device_id via_pci_autoload_table[] __initconst = { ++ /* OLPC XO 1.5 */ ++ { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), ++ .subvendor = 0x152d, .subdevice = 0x0833 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, via_pci_autoload_table); + + static const struct dev_pm_ops via_pm_ops = { + #ifdef CONFIG_PM_SLEEP diff --git a/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch new file mode 100644 index 000000000..074c856be --- /dev/null +++ b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 25 Sep 2018 19:44:13 +0100 +Subject: x86-32: Disable 3D-Now in generic config + +We want the 686 flavour to run on Geode LX and similar AMD family 5 +CPUs as well as family 6 and higher CPUs. This used to work with +CONFIG_M686=y. However commit 25d76ac88821 "x86/Kconfig: Explicitly +enumerate i686-class CPUs in Kconfig" in Linux 4.16 has made the +kernel require family 6 or higher. + +It looks like a sensible choice would be to enable CONFIG_MGEODE_LX +and CONFIG_X86_GENERIC (for more generic optimisations), but this +currently enables CONFIG_X86_USE_3D_NOW which will cause the kernel to +crash on CPUs without the AMD-specific 3D-Now instructions. + +Make CONFIG_X86_USE_3DNOW depend on CONFIG_X86_GENERIC being disabled. + +--- +--- a/arch/x86/Kconfig.cpu ++++ b/arch/x86/Kconfig.cpu +@@ -337,7 +337,7 @@ config X86_USE_PPRO_CHECKSUM + + config X86_USE_3DNOW + def_bool y +- depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML ++ depends on (MCYRIXIII || MK7 || MGEODE_LX) && !X86_GENERIC && !UML + + # + # P6_NOPs are a relatively minor optimization that require a family >= |