A general method for firmware loading
[Posted May 20, 2003 by corbet]
While most computer peripherals work right "out of the box," some will not
function properly until the host system has downloaded a blob of binary
firmware. Often as not, this firmware is proprietary software. In the
past, a number of drivers have gone into the kernel with proprietary
firmware bundled in. In the eyes of many, all devices have proprietary
firmware in them; there is little reason to be upset if, in some cases,
that firmware arrives via the kernel. But others (notably, the Debian
project) object to linking any sort of non-free software into their
kernel.
The end result is that the recommended way of dealing with devices needing
firmware downloads is to have a user-space process handle it. That way, no
non-free software need be linked into the kernel; as a side benefit, it
also gets easier to upgrade that firmware. The downloads have typically
been handled by way of a device-specific ioctl() call; each driver
includes its own, slightly different implementation.
In 2.5, the device model provides a framework which can be used to
clean up the handling of firmware downloads. All that was missing was an
actual implementation. Manuel Estrada Sainz has filled that gap, however,
with a patch adding an interface for
firmware loads.
In the new scheme, a device driver needing firmware for a particular device
makes a call to:
int request_firmware(struct firmware **fw, const char *name,
struct device *device);
Here, name is the name of the relevant device, and device
is its device model entry. This call will create a directory with the
given name under /sys/class/firmware and populate it with
two files called loading and data. A hotplug event is
then generated which, presumably, will inspire user space to find some
firmware to feed the device.
The resulting user-space process starts by setting the loading
sysfs attribute to a value of one. The actual firmware can then be written
to the data file; when the process is complete, the
loading file should be set back to zero. At that point,
request_firmware() will return to the driver with fw
pointing to the actual firmware data. The user-space process can chose to
abort the firmware load by writing -1 to the loading
attribute.
When the driver has loaded the firmware into its device, it should free up
the associated memory with:
void release_firmware(struct firmware *fw);
There has been talk of maintaining firmware within the kernel so that
subsequent requests can be satisfied without going back to user space. No
such mechanism has been implemented at this point, however. For situations
where it is not possible to wait for user space to react, there is a
request_firmware_nowait() function which will call back into the
driver when the firmware is available.
As of this writing, the new firmware code has not yet been merged into the
mainline kernel. Changes to the interface would not be surprising, but it
seems likely that 2.6 will have a generic firmware support interface that
is not vastly different from what is described here.
(
Log in to post comments)