Skip to contentSkip to conversation

firmware: doc revamp

PATCH In review Luis R. Rodriguez 4 participants 16 messages Dec 16, 2016 – Jan 19, 2017

Subsystems (5)
lore
Share & tools
lore

Luis R. Rodriguez

author maintainer
#0 lore raw

v2 cover firmware: doc revamp

This v2 has the small corrections on the revamp for the documentation for the firmware API. I'll follow this up with the drvdata API patches.

This is intended *after* the merge window, but posting now as we'll soon be in end of the year holidays.

Luis R. Rodriguez (5):
selftests: firmware: only modprobe if driver is missing
selftests: firmware: send expected errors to /dev/null
firmware: revamp firmware documentation
firmware: add SmPL report for custom fallback mechanism
firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

 Documentation/driver-api/firmware/built-in-fw.rst  |  38 ++++
 Documentation/driver-api/firmware/core.rst         |  16 ++
 .../driver-api/firmware/direct-fs-lookup.rst       |  30 +++
 .../driver-api/firmware/fallback-mechanisms.rst    | 215 +++++++++++++++++++++
 .../driver-api/firmware/firmware_cache.rst         |  51 +++++
 .../driver-api/firmware/fw_search_path.rst         |  26 +++
 Documentation/driver-api/firmware/index.rst        |  16 ++
 Documentation/driver-api/firmware/introduction.rst |  27 +++
 Documentation/driver-api/firmware/lookup-order.rst |  18 ++
 .../driver-api/firmware/request_firmware.rst       |  56 ++++++
 Documentation/driver-api/index.rst                 |   1 +
 Documentation/firmware_class/README                | 128 ------------
 drivers/firmware/dell_rbu.c                        |   1 +
 drivers/leds/leds-lp55xx-common.c                  |   1 +
 include/linux/firmware.h                           |   7 +
 .../api/request_firmware-custom-fallback.cocci     |  44 +++++
 tools/testing/selftests/firmware/fw_filesystem.sh  |  25 ++-
 17 files changed, 567 insertions(+), 133 deletions(-)
 create mode 100644 Documentation/driver-api/firmware/built-in-fw.rst
 create mode 100644 Documentation/driver-api/firmware/core.rst
 create mode 100644 Documentation/driver-api/firmware/direct-fs-lookup.rst
 create mode 100644 Documentation/driver-api/firmware/fallback-mechanisms.rst
 create mode 100644 Documentation/driver-api/firmware/firmware_cache.rst
 create mode 100644 Documentation/driver-api/firmware/fw_search_path.rst
 create mode 100644 Documentation/driver-api/firmware/index.rst
 create mode 100644 Documentation/driver-api/firmware/introduction.rst
 create mode 100644 Documentation/driver-api/firmware/lookup-order.rst
 create mode 100644 Documentation/driver-api/firmware/request_firmware.rst
 delete mode 100644 Documentation/firmware_class/README
 create mode 100644 scripts/coccinelle/api/request_firmware-custom-fallback.cocci
Signature · 1 line
2.10.1
author maintainer
#1 lore raw

PATCH v2 1/5 selftests: firmware: only modprobe if driver is missing

No need to load test_firmware if its already there. Also use a more generic form to recommend what is required to be built.

---
 tools/testing/selftests/firmware/fw_filesystem.sh | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
tools/testing/selftests/firmware/fw_filesystem.sh +17 -2
index 5c495ad7958a..c8ccdaa78479 100755
@@ -5,9 +5,24 @@
 # know so we can be sure we're not accidentally testing the user helper.
 set -e
 
-modprobe test_firmware
-
 DIR=/sys/devices/virtual/misc/test_firmware
+TEST_DIR=$(dirname $0)
+
+test_modprobe()
+{
+	if [ ! -d $DIR ]; then
+		echo "$0: $DIR not present"
+		echo "You must have the following enabled in your kernel:"
+		cat $TEST_DIR/config
+		exit 1
+	fi
+}
+
+trap "test_modprobe" EXIT
+
+if [ ! -d $DIR ]; then
+	modprobe test_firmware
+fi
 
 # CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
 # These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
Signature · 1 line
2.10.1
author maintainer
#2 lore raw

PATCH v2 2/5 selftests: firmware: send expected errors to /dev/null

In reply to Luis R. Rodriguez

Error that we expect should not be spilled to stdout.

Without this we get:

./fw_filesystem.sh: line 58: printf: write error: Invalid argument ./fw_filesystem.sh: line 63: printf: write error: No such device ./fw_filesystem.sh: line 69: echo: write error: No such file or directory ./fw_filesystem.sh: filesystem loading works ./fw_filesystem.sh: async filesystem loading works

With it:

./fw_filesystem.sh: filesystem loading works ./fw_filesystem.sh: async filesystem loading works

---
 tools/testing/selftests/firmware/fw_filesystem.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/testing/selftests/firmware/fw_filesystem.sh +3 -3
index c8ccdaa78479..e35691239350 100755
@@ -63,18 +63,18 @@ echo "ABCD0123" >"$FW"
 
 NAME=$(basename "$FW")
 
-if printf '\000' >"$DIR"/trigger_request; then
+if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
 	echo "$0: empty filename should not succeed" >&2
 	exit 1
 fi
 
-if printf '\000' >"$DIR"/trigger_async_request; then
+if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
 	echo "$0: empty filename should not succeed (async)" >&2
 	exit 1
 fi
 
 # Request a firmware that doesn't exist, it should fail.
-if echo -n "nope-$NAME" >"$DIR"/trigger_request; then
+if echo -n "nope-$NAME" >"$DIR"/trigger_request 2> /dev/null; then
 	echo "$0: firmware shouldn't have loaded" >&2
 	exit 1
 fi
Signature · 1 line
2.10.1
author maintainer
#3 lore raw

PATCH v2 3/5 firmware: revamp firmware documentation

In reply to Luis R. Rodriguez

Understanding this code is getting out of control without any notes. Give the firmware_class driver a much needed documentation love, and while at it convert it to the new sphinx documentation format.

v2: typos and small fixes

---
 Documentation/driver-api/firmware/built-in-fw.rst  |  38 ++++
 Documentation/driver-api/firmware/core.rst         |  16 ++
 .../driver-api/firmware/direct-fs-lookup.rst       |  30 ++++
 .../driver-api/firmware/fallback-mechanisms.rst    | 195 +++++++++++++++++++++
 .../driver-api/firmware/firmware_cache.rst         |  51 ++++++
 .../driver-api/firmware/fw_search_path.rst         |  26 +++
 Documentation/driver-api/firmware/index.rst        |  16 ++
 Documentation/driver-api/firmware/introduction.rst |  27 +++
 Documentation/driver-api/firmware/lookup-order.rst |  18 ++
 .../driver-api/firmware/request_firmware.rst       |  56 ++++++
 Documentation/driver-api/index.rst                 |   1 +
 Documentation/firmware_class/README                | 128 --------------
 12 files changed, 474 insertions(+), 128 deletions(-)
 create mode 100644 Documentation/driver-api/firmware/built-in-fw.rst
 create mode 100644 Documentation/driver-api/firmware/core.rst
 create mode 100644 Documentation/driver-api/firmware/direct-fs-lookup.rst
 create mode 100644 Documentation/driver-api/firmware/fallback-mechanisms.rst
 create mode 100644 Documentation/driver-api/firmware/firmware_cache.rst
 create mode 100644 Documentation/driver-api/firmware/fw_search_path.rst
 create mode 100644 Documentation/driver-api/firmware/index.rst
 create mode 100644 Documentation/driver-api/firmware/introduction.rst
 create mode 100644 Documentation/driver-api/firmware/lookup-order.rst
 create mode 100644 Documentation/driver-api/firmware/request_firmware.rst
 delete mode 100644 Documentation/firmware_class/README
Documentation/driver-api/firmware/built-in-fw.rst new file +38 -0
new file mode 100644
index 000000000000..7300e66857f8
@@ -0,0 +1,38 @@
+=================
+Built-in firmware
+=================
+
+Firmware can be built-in to the kernel, this means building the firmware
+into vmlinux directly, to enable avoiding having to look for firmware from
+the filesystem. Instead, firmware can be looked for inside the kernel
+directly. You can enable built-in firmware using the kernel configuration
+options:
+
+  * CONFIG_EXTRA_FIRMWARE
+  * CONFIG_EXTRA_FIRMWARE_DIR
+
+This should not be confused with CONFIG_FIRMWARE_IN_KERNEL, this is for drivers
+which enables firmware to be built as part of the kernel build process. This
+option, CONFIG_FIRMWARE_IN_KERNEL, will build all firmware for all drivers
+enabled which ship its firmware inside the Linux kernel source tree.
+
+There are a few reasons why you might want to consider building your firmware
+into the kernel with CONFIG_EXTRA_FIRMWARE though:
+
+* Speed
+* Firmware is needed for accessing the boot device, and the user doesn't
+  want to stuff the firmware into the boot initramfs.
+
+Even if you have these needs there are a few reasons why you may not be
+able to make use of built-in firmware:
+
+* Legalese - firmware is non-GPL compatible
+* Some firmware may be optional
+* Firmware upgrades are possible, therefore a new firmware would implicate
+  a complete kernel rebuild.
+* Some firmware files may be really large in size. The remote-proc subsystem
+  is an example subsystem which deals with these sorts of firmware
+* The firmware may need to be scraped out from some device specific location
+  dynamically, an example is calibration data for for some WiFi chipsets. This
+  calibration data can be unique per sold device.
+
Documentation/driver-api/firmware/core.rst new file +16 -0
new file mode 100644
index 000000000000..1d1688cbc078
@@ -0,0 +1,16 @@
+==========================
+Firmware API core features
+==========================
+
+The firmware API has a rich set of core features available. This section
+documents these features.
+
+.. toctree::
+
+   fw_search_path
+   built-in-fw
+   firmware_cache
+   direct-fs-lookup
+   fallback-mechanisms
+   lookup-order
+
Documentation/driver-api/firmware/direct-fs-lookup.rst new file +30 -0
new file mode 100644
index 000000000000..82b4d585a213
@@ -0,0 +1,30 @@
+========================
+Direct filesystem lookup
+========================
+
+Direct filesystem lookup is the most common form of firmware lookup performed
+by the kernel. The kernel looks for the firmware directly on the root
+filesystem in the paths documented in the section 'Firmware search paths'.
+The filesystem lookup is implemented in fw_get_filesystem_firmware(), it
+uses common core kernel file loader facility kernel_read_file_from_path().
+The max path allowed is PATH_MAX -- currently this is 4096 characters.
+
+It is recommended you keep /lib/firmware paths on your root filesystem,
+avoid having a separate partition for them in order to avoid possible
+races with lookups and avoid uses of the custom fallback mechanisms
+documented below.
+
+Firmware and initramfs
+----------------------
+
+Drivers which are built-in to the kernel should have the firmware integrated
+also as part of the initramfs used to boot the kernel given that otherwise
+a race is possible with loading the driver and the real rootfs not yet being
+available. Stuffing the firmware into initramfs resolves this race issue,
+however note that using initrd does not suffice to address the same race.
+
+There are circumstances that justify not wanting to include firmware into
+initramfs, such as dealing with large firmware firmware files for the
+remote-proc subsystem. For such cases using a userspace fallback mechanism
+is currently the only viable solution as only userspace can know for sure
+when the real rootfs is ready and mounted.
Documentation/driver-api/firmware/fallback-mechanisms.rst new file +195 -0

195 lines not on this page · raw message

Documentation/driver-api/firmware/firmware_cache.rst new file +51 -0

51 lines not on this page · raw message

Documentation/driver-api/firmware/fw_search_path.rst new file +26 -0
new file mode 100644
index 000000000000..a360f1009fa3
@@ -0,0 +1,26 @@
+=====================
+Firmware search paths
+=====================
+
+The following search paths are used to look for firmware on your
+root filesystem.
+
+* fw_path_para - module parameter - default is empty so this is ignored
+* /lib/firmware/updates/UTS_RELEASE/
+* /lib/firmware/updates/
+* /lib/firmware/UTS_RELEASE/
+* /lib/firmware/
+
+The module parameter ''path'' can be passed to the firmware_class module
+to activate the first optional custom fw_path_para. The custom path can
+only be up to 256 characters long. The kernel parameter passed would be:
+
+* 'firmware_class.path=$CUSTOMIZED_PATH'
+
+There is an alternative to customize the path at run time after bootup, you
+can use the file:
+
+* /sys/module/firmware_class/parameters/path
+
+You would echo into it your custom path and firmware requested will be
+searched for there first.
Documentation/driver-api/firmware/index.rst new file +16 -0
new file mode 100644
index 000000000000..1abe01793031
@@ -0,0 +1,16 @@
+==================
+Linux Firmware API
+==================
+
+.. toctree::
+
+   introduction
+   core
+   request_firmware
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
Documentation/driver-api/firmware/introduction.rst new file +27 -0
new file mode 100644
index 000000000000..211cb44eb972
@@ -0,0 +1,27 @@
+============
+Introduction
+============
+
+The firmware API enables kernel code to request files required
+for functionality from userspace, the uses vary:
+
+* Microcode for CPU errata
+* Device driver firmware, required to be loaded onto device
+  microcontrollers
+* Device driver information data (calibration data, EEPROM overrides),
+  some of which can be completely optional.
+
+Types of firmware requests
+==========================
+
+There are two types of calls:
+
+* Synchronous
+* Asynchronous
+
+Which one you use vary depending on your requirements, the rule of thumb
+however is you should strive to use the asynchronous APIs unless you also
+are already using asynchronous initialization mechanisms which will not
+stall or delay boot. Even if loading firmware does not take a lot of time
+processing firmware might, and this can still delay boot or initialization,
+as such mechanisms such as asynchronous probe can help supplement drivers.
Documentation/driver-api/firmware/lookup-order.rst new file +18 -0
new file mode 100644
index 000000000000..88c81739683c
@@ -0,0 +1,18 @@
+=====================
+Firmware lookup order
+=====================
+
+Different functionality is available to enable firmware to be found.
+Below is chronological order of how firmware will be looked for once
+a driver issues a firmware API call.
+
+* The ''Built-in firmware'' is checked first, if the firmware is present we
+  return it immediately
+* The ''Firmware cache'' is looked at next. If the firmware is found we
+  return it immediately
+* The ''Direct filesystem lookup'' is performed next, if found we
+  return it immediately
+* If no firmware has been found and the fallback mechanism was enabled
+  the sysfs interface is created. After this either a kobject uevent
+  is issued or the custom firmware loading is relied upon for firmware
+  loading up to the timeout value.
Documentation/driver-api/firmware/request_firmware.rst new file +56 -0

56 lines not on this page · raw message

Documentation/driver-api/index.rst +1 -0
index 5475a2807e7a..d6f4ad1a872d 100644
@@ -30,6 +30,7 @@ available subsections can be seen below.
    miscellaneous
    vme
    80211/index
+   firmware/index
 
 .. only::  subproject and html
 
Documentation/firmware_class/README deleted +0 -128

128 lines not on this page · raw message

Signature · 1 line
2.10.1
#4 lore raw

Re: [PATCH v2 3/5] firmware: revamp firmware documentation

Quoted 7 lines · Luis R. Rodriguez

Understanding this code is getting out of control without any notes. Give the firmware_class driver a much needed documentation love, and while at it convert it to the new sphinx documentation format.

v2: typos and small fixes

[...]

Documentation/driver-api/firmware/fallback-mechanisms.rst line 86

Quoted 2 lines
Documentation/driver-api/firmware/fallback-mechanisms.rst new file +2 -0
+To upload firmware you will echo 1 onto the loading file to indicate
+you are loading firmware. You then cat the firmware into the data file,

s/cat/write/?

Documentation/driver-api/firmware/fallback-mechanisms.rst line 139

Quoted 2 lines
Documentation/driver-api/firmware/fallback-mechanisms.rst new file +2 -0
+Refer to do_firmware_uevent() for details of the kobject event variables
+setup. Variables passwdd with a kobject add event:

"passed" or what? I'm not quite understanding the last sentence anyway.

Documentation/driver-api/firmware/firmware_cache.rst line 33

Quoted 5 lines
Documentation/driver-api/firmware/firmware_cache.rst new file +5 -0
+* If an asynchronous call is used the firmware cache is only set up for a
+  device if if the second argument (uevent) to request_firmware_nowait() is
+  true. When uevent is true it requests that a kobject uevent be sent to
+  userspace for the firmware request. For details refer to the Fackback
+  mechanism documented below.

Is that "fackback" typo intentional? Pretty funny at least :)

But this was really good, thanks. I learned a lot.

Signature · 1 line
Kalle Valo
author maintainer
#5 lore raw

PATCH v2 4/5 firmware: add SmPL report for custom fallback mechanism

In reply to Luis R. Rodriguez

Even though most distributions today disable the fallback mechanism by default we've determined that we cannot remove them from the kernel. This is not well understood so document the reason and logic behind that.

Recent discussions suggest some future userspace development prospects which may enable fallback mechanisms to become more useful while avoiding some historical issues. These discussions have made it clear though that there is less value to the custom fallback mechanism and an alternative can be provided in the future. Its also clear that some old users of the custom fallback mechanism were using it as a copy and paste error. Because of all this add a Coccinelle SmPL patch to help maintainers police for new incorrect users of the custom fallback mechanism.

Best we can do for now then is police for new users of the custom fallback mechanism and and fix incorrect users when they are spotted. Drivers can only be transitioned out of the custom fallback mechanism once we know old userspace cannot be not be broken by a kernel change.

The current SmPL patch reports:

$ export COCCI=scripts/coccinelle/api/request_firmware-custom-fallback.cocci
$ make coccicheck MODE=report

drivers/leds/leds-lp55xx-common.c:227:8-31: WARNING: please check if driver really needs a custom fallback mechanism drivers/firmware/dell_rbu.c:622:17-40: WARNING: please check if driver really needs a custom fallback mechanism

Cc Richard Purdie <[email protected]>
Cc Jacek Anaszewski <[email protected]>
Cc Abhay Salunke <[email protected]>
---
 .../driver-api/firmware/fallback-mechanisms.rst    | 17 ++++++++++
 .../api/request_firmware-custom-fallback.cocci     | 37 ++++++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 scripts/coccinelle/api/request_firmware-custom-fallback.cocci
Documentation/driver-api/firmware/fallback-mechanisms.rst +17 -0
index d19354794e67..b87a292153c6 100644
@@ -28,6 +28,12 @@ CONFIG_FW_LOADER_USER_HELPER_FALLBACK=n
 the kobject uevent fallback mechanism will never take effect even
 for request_firmware_nowait() when uevent is set to true.
 
+Although the fallback mechanisms are not used widely today they cannot be
+removed from the kernel since some old userspace may exist which could
+entirely depend on the fallback mechanism enabled with the kernel config option
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK. In the future though drivers may opt
+to embrace a different API which provides alternative fallback mechanisms.
+
 Justifying the firmware fallback mechanism
 ==========================================
 
@@ -176,6 +182,17 @@ but you want to suppress kobject uevents, as you have a custom solution which
 will monitor for your device addition into the device hierarchy somehow and
 load firmware for you through a custom path.
 
+The custom fallback mechanism can often be enabled by mistake. We currently
+have only 2 users of it, and little justification to enable it for other users.
+Since it is a common driver developer mistake to enable it, help police for
+new users of the custom fallback mechanism with::
+
+        $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
+        $ make coccicheck MODE=report
+
+Drivers can only be transitioned out of the custom fallback mechanism
+once we know old userspace cannot be not be broken by a kernel change.
+
 Firmware fallback timeout
 =========================
 
scripts/coccinelle/api/request_firmware-custom-fallback.cocci new file +37 -0
new file mode 100644
index 000000000000..c7598cfc4780
@@ -0,0 +1,37 @@
+// Avoid the firmware custom fallback mechanism at all costs
+//
+// request_firmware_nowait() API enables explicit request for use of the custom
+// fallback mechanism if firmware is not found. Chances are high its use is
+// just a copy and paste bug. Before you fix the driver be sure to *verify* no
+// custom firmware loading tool exists that would otherwise break if we replace
+// the driver to use the uevent fallback mechanism.
+//
+// Confidence: High
+//
+// Reason for low confidence:
+//
+// Copyright: (C) 2016 Luis R. Rodriguez <[email protected]> GPLv2.
+//
+// Options: --include-headers
+
+virtual report
+virtual context
+
+@ r1 depends on report || context @
+expression mod, name, dev, gfp, drv, cb;
+position p;
+@@
+
+(
+*request_firmware_nowait@p(mod, false, name, dev, gfp, drv, cb)
+|
+*request_firmware_nowait@p(mod, 0, name, dev, gfp, drv, cb)
+|
+*request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)
+)
+
+@script:python depends on report@
+p << r1.p;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: please check if driver really needs a custom fallback mechanism")
Signature · 1 line
2.10.1
#6 lore raw

Re: [PATCH v2 4/5] firmware: add SmPL report for custom fallback mechanism

Quoted 3 lines · Luis R. Rodriguez

Even though most distributions today disable the fallback mechanism by default we've determined that we cannot remove them from the kernel. This is not well understood so document the reason and logic behind that.

Well, the biggest reason is that some distros still rely on this. I've seen new products being made that rely on it, so let's please stop treating it like it is somehow a "deprecated" interface. We can't get rid of it, so we just have to live with it, for forever, sorry.

greg k-h

author maintainer
#7 lore raw

Re: [PATCH v2 4/5] firmware: add SmPL report for custom fallback mechanism

Quoted 7 lines · Greg KH
Quoted 3 lines · Luis R. Rodriguez

Even though most distributions today disable the fallback mechanism by default we've determined that we cannot remove them from the kernel. This is not well understood so document the reason and logic behind that.

Well, the biggest reason is that some distros still rely on this. I've seen new products being made that rely on it,

Let's be a bit more precise: upstream there are only two driver relying on this and I've learned about the non-upstream uses which folks have been calling for ensuring this functionality is kept for: a) non-upstream mobile 802.11 drivers or upstream 802.11 drivers with slight out-of-tree customizations with a requirements to get calibration data using custom mechanisms b) remote-proc users with huge firmware requirements for which initramfs is not well suited for.

I've taken these requirements seriously in this series. Perhaps this is not well reflected in the series enough so let me elaborate.

Quoted 2 lines

so let's please stop
treating it like it is somehow a "deprecated" interface.

In this series I no longer treats it as a deprecated interface. This series however does acknowledge a bit of the drawbacks and cautions folks should take when using these interfaces though. These issues are real.

Quoted 1 line

We can't get rid of it,

I am way past that point. I've had to personally deal with both pushes now: the misplaced crusade against the both the mislabeled "firmware usermode helper" which was originally actually caused by the "firmware timeout issue" and now properly diagnosed, and later those out of a) and b) users. I've listened to both carefully and given this much thought and discussion at Plumbers through hallway tracks and private exchanges including with systemd folks and have tried to itemize the current drawbacks and also finally address them. One thing is clear: the out of tree custom fallback users simply need a custom way to load firmware, the use of the kobject driven uevent mechanism should suffice, its just we never had a clear documented way to enable custom solutions. In discussions with Tom Gundersen, and Johannes Berg it seems we can enable these users easily with the kobject uevent fallback mechanism, we just need to address the existing drawback issues. This means if taking into consideration upstream and non-upstream drivers -- the custom fallback mechanism becomes more of a legacy thing. So sure -- we cannot remove it, but we should avoid more propagation of it by mistake upstream, and hence this patch.

To this end my new goal is to first properly label and document the interfaces first, then to itemize the drawbacks of the "custom firmware fallback mechanism", avoid further copy and paste bugs which implicated the "custom firmware fallback mechanism" and were frequent before (its the purpose of this patch). Then work with kernel/systemd folks to provide a proper resolution to the drawbacks as best as we can for the general uevent kobject fallback mechanism. This solution will work for the existing request_firmware_nowait() API, so it will benefit from it, but only once that is properly hashed out will I plan to add equivalent a fallback mechanism to the drvdata API.

Quoted 1 line

so we just have to live with it, for forever, sorry.

This documentation revamp acknowledges this, but paves the way for what we need to do for the old users of the custom fallback mechanism and of the users which I've heard from which need a type of fallback mechanism. The next patch white-lists though the few old upstream uses of the custom fallback mechanism.

The plan is to never remove the old custom fallback mechanism then. The drvdata API will start without any fallback mechanism to start with but the plan is to incorporate support for one once we iron out all the kinks for a clean solution for a general fallback mechanism we are happy with.

The old custom fallback mechanism will be kept forever.

Luis

#8 lore raw

Re: [PATCH v2 4/5] firmware: add SmPL report for custom fallback mechanism

Quoted 9 lines · Luis R. Rodriguez
Quoted 7 lines · Greg KH
Quoted 3 lines · Luis R. Rodriguez

Even though most distributions today disable the fallback mechanism by default we've determined that we cannot remove them from the kernel. This is not well understood so document the reason and logic behind that.

Well, the biggest reason is that some distros still rely on this. I've seen new products being made that rely on it,

Quoted 6 lines

Let's be a bit more precise: upstream there are only two driver relying on this and I've learned about the non-upstream uses which folks have been calling for ensuring this functionality is kept for: a) non-upstream mobile 802.11 drivers or upstream 802.11 drivers with slight out-of-tree customizations with a requirements to get calibration data using custom mechanisms b) remote-proc users with huge firmware requirements for which initramfs is not well suited for.

That b) is a lot of devices, I know of a few million phones in the wild right now that rely on it. And millions is a pretty big number :)

Anyway, thanks for addressing my concerns, I'm guessing you will respin these remaining patches and resend them as I think there were still some comments on them? I took the first 3 here.

Is the "drvdata" code ready in your opinion to be merged / reviewed yet?

thanks,

greg k-h

author maintainer
#9 lore raw

Re: [PATCH v2 4/5] firmware: add SmPL report for custom fallback mechanism

Quoted 17 lines · Greg KH
Quoted 9 lines · Luis R. Rodriguez
Quoted 7 lines · Greg KH
Quoted 3 lines · Luis R. Rodriguez

Even though most distributions today disable the fallback mechanism by default we've determined that we cannot remove them from the kernel. This is not well understood so document the reason and logic behind that.

Well, the biggest reason is that some distros still rely on this. I've seen new products being made that rely on it,

Quoted 6 lines

Let's be a bit more precise: upstream there are only two driver relying on this and I've learned about the non-upstream uses which folks have been calling for ensuring this functionality is kept for: a) non-upstream mobile 802.11 drivers or upstream 802.11 drivers with slight out-of-tree customizations with a requirements to get calibration data using custom mechanisms b) remote-proc users with huge firmware requirements for which initramfs is not well suited for.

Quoted 6 lines

That b) is a lot of devices, I know of a few million phones in the wild right now that rely on it. And millions is a pretty big number :)

Anyway, thanks for addressing my concerns, I'm guessing you will respin these remaining patches and resend them as I think there were still some comments on them? I took the first 3 here.

Yeah sure, I will address these comments.

Quoted 1 line

Is the "drvdata" code ready in your opinion to be merged / reviewed yet?

drvdata stuff is ready as can be but after the sysdata/drvdata rename change I failed to change one of the p54 files, I also forgot to Cc Boris on the microcode conversion so I can just respin the drvdata series again as a separate series right after I address the concerns for this series.

Luis

author maintainer
#10 lore raw

PATCH v2 5/5 firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

In reply to Luis R. Rodriguez

We need to ensure that when driver developers use the custom firmware fallback mechanism it was not a copy and paste bug. These use cases on upstream drivers are rare, we only have 2 upstream users and its for really old drivers. Since valid uses are rare but possible enable a white-list for its use, and use this same white-list annotation to refer to the documentation covering the custom use case.

New faulty users can be reported via 0-day now.

---
 Documentation/driver-api/firmware/fallback-mechanisms.rst     | 7 +++++--
 drivers/firmware/dell_rbu.c                                   | 1 +
 drivers/leds/leds-lp55xx-common.c                             | 1 +
 include/linux/firmware.h                                      | 7 +++++++
 scripts/coccinelle/api/request_firmware-custom-fallback.cocci | 9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)
Documentation/driver-api/firmware/fallback-mechanisms.rst +5 -2
index b87a292153c6..73f509a8d2de 100644
@@ -184,8 +184,11 @@ load firmware for you through a custom path.
 
 The custom fallback mechanism can often be enabled by mistake. We currently
 have only 2 users of it, and little justification to enable it for other users.
-Since it is a common driver developer mistake to enable it, help police for
-new users of the custom fallback mechanism with::
+Since it is a common driver developer mistake to enable it, driver developers
+should use DECLARE_FW_CUSTOM_FALLBACK() to both white-list and validate their
+use and also refer to the documentation for the custom loading solution.
+
+Invalid users of the custom fallback mechanism can be policed using::
 
         $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
         $ make coccicheck MODE=report
drivers/firmware/dell_rbu.c +1 -0
index 2f452f1f7c8a..3f2aa35bc54d 100644
@@ -586,6 +586,7 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
 	return size;
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/dell_rbu.txt");
 static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
 				    struct bin_attribute *bin_attr,
 				    char *buffer, loff_t pos, size_t count)
drivers/leds/leds-lp55xx-common.c +1 -0
index 5377f22ff994..04161428ee3b 100644
@@ -219,6 +219,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 	release_firmware(chip->fw);
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/leds/leds-lp55xx.txt");
 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 {
 	const char *name = chip->cl->name;
include/linux/firmware.h +7 -0
index b1f9f0ccb8ac..e6ca19c03dcc 100644
@@ -8,6 +8,13 @@
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
 
+/*
+ * Helper for scripts/coccinelle/api/request_firmware-custom-fallback.cocci
+ * and so users can also easily search for the documentation for the
+ * respectively needed custom fallback mechanism.
+ */
+#define DECLARE_FW_CUSTOM_FALLBACK(__usermode_helper)
+
 struct firmware {
 	size_t size;
 	const u8 *data;
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +8 -1
index c7598cfc4780..68cacab35b76 100644
@@ -17,6 +17,13 @@
 virtual report
 virtual context
 
+@ r0 depends on report || context @
+declarer name DECLARE_FW_CUSTOM_FALLBACK;
+expression E;
+@@
+
+DECLARE_FW_CUSTOM_FALLBACK(E);
+
 @ r1 depends on report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
@@ -30,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)
 )
 
-@script:python depends on report@
+@script:python depends on report && !r0 @
 p << r1.p;
 @@
 
Signature · 1 line
2.10.1
#11 lore raw

Re: [PATCH v2 5/5] firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

Quoted 103 lines · Luis R. Rodriguez

We need to ensure that when driver developers use the custom firmware fallback mechanism it was not a copy and paste bug. These use cases on upstream drivers are rare, we only have 2 upstream users and its for really old drivers. Since valid uses are rare but possible enable a white-list for its use, and use this same white-list annotation to refer to the documentation covering the custom use case.

New faulty users can be reported via 0-day now.

---
 Documentation/driver-api/firmware/fallback-mechanisms.rst     | 7 +++++--
 drivers/firmware/dell_rbu.c                                   | 1 +
 drivers/leds/leds-lp55xx-common.c                             | 1 +
 include/linux/firmware.h                                      | 7 +++++++
 scripts/coccinelle/api/request_firmware-custom-fallback.cocci | 9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)
Documentation/driver-api/firmware/fallback-mechanisms.rst +5 -2
index b87a292153c6..73f509a8d2de 100644
@@ -184,8 +184,11 @@ load firmware for you through a custom path.
 
 The custom fallback mechanism can often be enabled by mistake. We currently
 have only 2 users of it, and little justification to enable it for other users.
-Since it is a common driver developer mistake to enable it, help police for
-new users of the custom fallback mechanism with::
+Since it is a common driver developer mistake to enable it, driver developers
+should use DECLARE_FW_CUSTOM_FALLBACK() to both white-list and validate their
+use and also refer to the documentation for the custom loading solution.
+
+Invalid users of the custom fallback mechanism can be policed using::
 
         $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
         $ make coccicheck MODE=report
drivers/firmware/dell_rbu.c +1 -0
index 2f452f1f7c8a..3f2aa35bc54d 100644
@@ -586,6 +586,7 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
 	return size;
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/dell_rbu.txt");
 static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
 				    struct bin_attribute *bin_attr,
 				    char *buffer, loff_t pos, size_t count)
drivers/leds/leds-lp55xx-common.c +1 -0
index 5377f22ff994..04161428ee3b 100644
@@ -219,6 +219,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 	release_firmware(chip->fw);
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/leds/leds-lp55xx.txt");
 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 {
 	const char *name = chip->cl->name;
include/linux/firmware.h +7 -0
index b1f9f0ccb8ac..e6ca19c03dcc 100644
@@ -8,6 +8,13 @@
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
 
+/*
+ * Helper for scripts/coccinelle/api/request_firmware-custom-fallback.cocci
+ * and so users can also easily search for the documentation for the
+ * respectively needed custom fallback mechanism.
+ */
+#define DECLARE_FW_CUSTOM_FALLBACK(__usermode_helper)
+
 struct firmware {
 	size_t size;
 	const u8 *data;
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +7 -0
index c7598cfc4780..68cacab35b76 100644
@@ -17,6 +17,13 @@
 virtual report
 virtual context
 
+@ r0 depends on report || context @
+declarer name DECLARE_FW_CUSTOM_FALLBACK;
+expression E;
+@@
+
+DECLARE_FW_CUSTOM_FALLBACK(E);
+
 @ r1 depends on report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 37

Quoted 1 line
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +0 -0
@@ -30,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)

It looks suspicious that your added a new rule r0, that the python rule below depends on r0 failing, and that the rule with the * (context mode) does not depend on r0 in any way.

julia

Quoted 11 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +1 -2
 )
 
-@script:python depends on report@
+@script:python depends on report && !r0 @
 p << r1.p;
 @@
 
--

2.10.1

author maintainer
#12 lore raw

Re: [PATCH v2 5/5] firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

Quoted 96 lines · Julia Lawall
Quoted 92 lines · Luis R. Rodriguez

We need to ensure that when driver developers use the custom firmware fallback mechanism it was not a copy and paste bug. These use cases on upstream drivers are rare, we only have 2 upstream users and its for really old drivers. Since valid uses are rare but possible enable a white-list for its use, and use this same white-list annotation to refer to the documentation covering the custom use case.

New faulty users can be reported via 0-day now.

---
 Documentation/driver-api/firmware/fallback-mechanisms.rst     | 7 +++++--
 drivers/firmware/dell_rbu.c                                   | 1 +
 drivers/leds/leds-lp55xx-common.c                             | 1 +
 include/linux/firmware.h                                      | 7 +++++++
 scripts/coccinelle/api/request_firmware-custom-fallback.cocci | 9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)
Documentation/driver-api/firmware/fallback-mechanisms.rst +5 -2
index b87a292153c6..73f509a8d2de 100644
@@ -184,8 +184,11 @@ load firmware for you through a custom path.
 
 The custom fallback mechanism can often be enabled by mistake. We currently
 have only 2 users of it, and little justification to enable it for other users.
-Since it is a common driver developer mistake to enable it, help police for
-new users of the custom fallback mechanism with::
+Since it is a common driver developer mistake to enable it, driver developers
+should use DECLARE_FW_CUSTOM_FALLBACK() to both white-list and validate their
+use and also refer to the documentation for the custom loading solution.
+
+Invalid users of the custom fallback mechanism can be policed using::
 
         $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
         $ make coccicheck MODE=report
drivers/firmware/dell_rbu.c +1 -0
index 2f452f1f7c8a..3f2aa35bc54d 100644
@@ -586,6 +586,7 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
 	return size;
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/dell_rbu.txt");
 static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
 				    struct bin_attribute *bin_attr,
 				    char *buffer, loff_t pos, size_t count)
drivers/leds/leds-lp55xx-common.c +1 -0
index 5377f22ff994..04161428ee3b 100644
@@ -219,6 +219,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 	release_firmware(chip->fw);
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/leds/leds-lp55xx.txt");
 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 {
 	const char *name = chip->cl->name;
include/linux/firmware.h +7 -0
index b1f9f0ccb8ac..e6ca19c03dcc 100644
@@ -8,6 +8,13 @@
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
 
+/*
+ * Helper for scripts/coccinelle/api/request_firmware-custom-fallback.cocci
+ * and so users can also easily search for the documentation for the
+ * respectively needed custom fallback mechanism.
+ */
+#define DECLARE_FW_CUSTOM_FALLBACK(__usermode_helper)
+
 struct firmware {
 	size_t size;
 	const u8 *data;
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +0 -0
index c7598cfc4780..68cacab35b76 100644
@@ -17,6 +17,13 @@
 virtual report
 virtual context
 
Quoted 16 lines

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 37

Quoted 12 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +7 -0
+@ r0 depends on report || context @
+declarer name DECLARE_FW_CUSTOM_FALLBACK;
+expression E;
+@@
+
+DECLARE_FW_CUSTOM_FALLBACK(E);
+
 @ r1 depends on report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
@@ -30,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)

It looks suspicious that your added a new rule r0, that the python rule below depends on r0 failing, and that the rule with the * (context mode) does not depend on r0 in any way.

You're right, the context mode would report all cases, I've changed it as follows:

scripts/coccinelle/api/request_firmware-custom-fallback.cocci +2 -2
index 68cacab35b76..9548e5be9c0e 100644
@@ -24,7 +24,7 @@ expression E;
 
 DECLARE_FW_CUSTOM_FALLBACK(E);
 
-@ r1 depends on report || context @
+@ r1 depends on !r0 && report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
 @@
@@ -37,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)
 )
 
-@script:python depends on report && !r0 @
+@script:python depends on report && r1 @
 p << r1.p;
 @@
 
author maintainer
#13 lore raw

Re: [PATCH v2 5/5] firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

Quoted 6 lines · Luis R. Rodriguez
Quoted 3 lines · Julia Lawall

It looks suspicious that your added a new rule r0, that the python rule below depends on r0 failing, and that the rule with the * (context mode) does not depend on r0 in any way.

You're right, the context mode would report all cases, I've changed it as follows:

That still didn't cut it.. will dig further.

Luis

#14 lore raw

Re: [PATCH v2 5/5] firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

In reply to Luis R. Rodriguez
Quoted 130 lines · Luis R. Rodriguez
Quoted 96 lines · Julia Lawall
Quoted 92 lines · Luis R. Rodriguez

We need to ensure that when driver developers use the custom firmware fallback mechanism it was not a copy and paste bug. These use cases on upstream drivers are rare, we only have 2 upstream users and its for really old drivers. Since valid uses are rare but possible enable a white-list for its use, and use this same white-list annotation to refer to the documentation covering the custom use case.

New faulty users can be reported via 0-day now.

---
 Documentation/driver-api/firmware/fallback-mechanisms.rst     | 7 +++++--
 drivers/firmware/dell_rbu.c                                   | 1 +
 drivers/leds/leds-lp55xx-common.c                             | 1 +
 include/linux/firmware.h                                      | 7 +++++++
 scripts/coccinelle/api/request_firmware-custom-fallback.cocci | 9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)
Documentation/driver-api/firmware/fallback-mechanisms.rst +5 -2
index b87a292153c6..73f509a8d2de 100644
@@ -184,8 +184,11 @@ load firmware for you through a custom path.
 
 The custom fallback mechanism can often be enabled by mistake. We currently
 have only 2 users of it, and little justification to enable it for other users.
-Since it is a common driver developer mistake to enable it, help police for
-new users of the custom fallback mechanism with::
+Since it is a common driver developer mistake to enable it, driver developers
+should use DECLARE_FW_CUSTOM_FALLBACK() to both white-list and validate their
+use and also refer to the documentation for the custom loading solution.
+
+Invalid users of the custom fallback mechanism can be policed using::
 
         $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
         $ make coccicheck MODE=report
drivers/firmware/dell_rbu.c +1 -0
index 2f452f1f7c8a..3f2aa35bc54d 100644
@@ -586,6 +586,7 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
 	return size;
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/dell_rbu.txt");
 static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
 				    struct bin_attribute *bin_attr,
 				    char *buffer, loff_t pos, size_t count)
drivers/leds/leds-lp55xx-common.c +1 -0
index 5377f22ff994..04161428ee3b 100644
@@ -219,6 +219,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 	release_firmware(chip->fw);
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/leds/leds-lp55xx.txt");
 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 {
 	const char *name = chip->cl->name;
include/linux/firmware.h +7 -0
index b1f9f0ccb8ac..e6ca19c03dcc 100644
@@ -8,6 +8,13 @@
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
 
+/*
+ * Helper for scripts/coccinelle/api/request_firmware-custom-fallback.cocci
+ * and so users can also easily search for the documentation for the
+ * respectively needed custom fallback mechanism.
+ */
+#define DECLARE_FW_CUSTOM_FALLBACK(__usermode_helper)
+
 struct firmware {
 	size_t size;
 	const u8 *data;
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +0 -0
index c7598cfc4780..68cacab35b76 100644
@@ -17,6 +17,13 @@
 virtual report
 virtual context
 
Quoted 16 lines

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 37

Quoted 12 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +7 -0
+@ r0 depends on report || context @
+declarer name DECLARE_FW_CUSTOM_FALLBACK;
+expression E;
+@@
+
+DECLARE_FW_CUSTOM_FALLBACK(E);
+
 @ r1 depends on report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
@@ -30,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)

It looks suspicious that your added a new rule r0, that the python rule below depends on r0 failing, and that the rule with the * (context mode) does not depend on r0 in any way.

You're right, the context mode would report all cases, I've changed it as follows:

scripts/coccinelle/api/request_firmware-custom-fallback.cocci +1 -1
index 68cacab35b76..9548e5be9c0e 100644
@@ -24,7 +24,7 @@ expression E;
 
 DECLARE_FW_CUSTOM_FALLBACK(E);
 
-@ r1 depends on report || context @
+@ r1 depends on !r0 && report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
 @@

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 42

Quoted 7 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +1 -1
@@ -37,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)
 )
 
-@script:python depends on report && !r0 @
+@script:python depends on report && r1 @
 p << r1.p;
 @@

It is never useful in a python rule to mention an inherited rule in the depends line that is also mentioned in the metavariable list. A python rule is only applied if all the metavariables are bound. Thus, the use of r1.p means that r1 has to be satisfied.

If you need further suggestions, just send the whole thing again, and I will take a look.

julia

author maintainer
#15 lore raw

Re: [PATCH v2 5/5] firmware: add DECLARE_FW_CUSTOM_FALLBACK() annotation

Quoted 147 lines · Julia Lawall
Quoted 130 lines · Luis R. Rodriguez
Quoted 96 lines · Julia Lawall
Quoted 92 lines · Luis R. Rodriguez

We need to ensure that when driver developers use the custom firmware fallback mechanism it was not a copy and paste bug. These use cases on upstream drivers are rare, we only have 2 upstream users and its for really old drivers. Since valid uses are rare but possible enable a white-list for its use, and use this same white-list annotation to refer to the documentation covering the custom use case.

New faulty users can be reported via 0-day now.

---
 Documentation/driver-api/firmware/fallback-mechanisms.rst     | 7 +++++--
 drivers/firmware/dell_rbu.c                                   | 1 +
 drivers/leds/leds-lp55xx-common.c                             | 1 +
 include/linux/firmware.h                                      | 7 +++++++
 scripts/coccinelle/api/request_firmware-custom-fallback.cocci | 9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)
Documentation/driver-api/firmware/fallback-mechanisms.rst +5 -2
index b87a292153c6..73f509a8d2de 100644
@@ -184,8 +184,11 @@ load firmware for you through a custom path.
 
 The custom fallback mechanism can often be enabled by mistake. We currently
 have only 2 users of it, and little justification to enable it for other users.
-Since it is a common driver developer mistake to enable it, help police for
-new users of the custom fallback mechanism with::
+Since it is a common driver developer mistake to enable it, driver developers
+should use DECLARE_FW_CUSTOM_FALLBACK() to both white-list and validate their
+use and also refer to the documentation for the custom loading solution.
+
+Invalid users of the custom fallback mechanism can be policed using::
 
         $ export COCCI=scripts/coccinelle/api/request_firmware-avoid-init-probe-init.cocci
         $ make coccicheck MODE=report
drivers/firmware/dell_rbu.c +1 -0
index 2f452f1f7c8a..3f2aa35bc54d 100644
@@ -586,6 +586,7 @@ static ssize_t read_rbu_image_type(struct file *filp, struct kobject *kobj,
 	return size;
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/dell_rbu.txt");
 static ssize_t write_rbu_image_type(struct file *filp, struct kobject *kobj,
 				    struct bin_attribute *bin_attr,
 				    char *buffer, loff_t pos, size_t count)
drivers/leds/leds-lp55xx-common.c +1 -0
index 5377f22ff994..04161428ee3b 100644
@@ -219,6 +219,7 @@ static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
 	release_firmware(chip->fw);
 }
 
+DECLARE_FW_CUSTOM_FALLBACK("Documentation/leds/leds-lp55xx.txt");
 static int lp55xx_request_firmware(struct lp55xx_chip *chip)
 {
 	const char *name = chip->cl->name;
include/linux/firmware.h +7 -0
index b1f9f0ccb8ac..e6ca19c03dcc 100644
@@ -8,6 +8,13 @@
 #define FW_ACTION_NOHOTPLUG 0
 #define FW_ACTION_HOTPLUG 1
 
+/*
+ * Helper for scripts/coccinelle/api/request_firmware-custom-fallback.cocci
+ * and so users can also easily search for the documentation for the
+ * respectively needed custom fallback mechanism.
+ */
+#define DECLARE_FW_CUSTOM_FALLBACK(__usermode_helper)
+
 struct firmware {
 	size_t size;
 	const u8 *data;
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +0 -0
index c7598cfc4780..68cacab35b76 100644
@@ -17,6 +17,13 @@
 virtual report
 virtual context
 
Quoted 16 lines

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 37

Quoted 12 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +7 -0
+@ r0 depends on report || context @
+declarer name DECLARE_FW_CUSTOM_FALLBACK;
+expression E;
+@@
+
+DECLARE_FW_CUSTOM_FALLBACK(E);
+
 @ r1 depends on report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
@@ -30,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)

It looks suspicious that your added a new rule r0, that the python rule below depends on r0 failing, and that the rule with the * (context mode) does not depend on r0 in any way.

You're right, the context mode would report all cases, I've changed it as follows:

scripts/coccinelle/api/request_firmware-custom-fallback.cocci +1 -1
index 68cacab35b76..9548e5be9c0e 100644
@@ -24,7 +24,7 @@ expression E;
 
 DECLARE_FW_CUSTOM_FALLBACK(E);
 
-@ r1 depends on report || context @
+@ r1 depends on !r0 && report || context @
 expression mod, name, dev, gfp, drv, cb;
 position p;
 @@

scripts/coccinelle/api/request_firmware-custom-fallback.cocci position p; · line 42

Quoted 7 lines
scripts/coccinelle/api/request_firmware-custom-fallback.cocci +1 -1
@@ -37,7 +37,7 @@ position p;
 *request_firmware_nowait@p(mod, FW_ACTION_NOHOTPLUG, name, dev, gfp, drv, cb)
 )
 
-@script:python depends on report && !r0 @
+@script:python depends on report && r1 @
 p << r1.p;
 @@

It is never useful in a python rule to mention an inherited rule in the depends line that is also mentioned in the metavariable list. A python rule is only applied if all the metavariables are bound. Thus, the use of r1.p means that r1 has to be satisfied.

Quoted 2 lines

If you need further suggestions, just send the whole thing again, and I will take a look.

Sure, I can just also drop context support for now as what we really are after are the reports, and that works well.

Luis