Re: non-free firmware
Sven Luther wrote:
>No, i don't think this was the kind of framework i was refering to,
Well, another related issue is what format the firmware file should be stored
in -- I advocate a fixed endianness so it doesn't depend on the host CPU
details, for instance.
>more of a
>set of rules on how we would patch the drivers to make them request_firmware
>aware.
Ideally, you call "request_firmware" in the driver code immediately before the
microcode is uploaded to the peripheral. The firmware is stored in main
memory until the upload and then the memory is released.
In a driver which minimizes its lock use, this gives pretty good results.
Since it depends on hotplug to get the firmware, it won't work until root is
mounted (until udev is made to run in the initramfs).
Spinlocks made this more complicated. request_firmware must be called in a
situation where sleeping is permitted. Accordingly, you must trace the call
sequence (of the function uploading the microcode to the peripheral) back
upwards to the first point where no spinlocks are held, and call it there.
The memory should be released on all exit paths after the upload, which can
usually be done in the very same function you call "request_firmware" in.
The tg3 driver was a bear, because spinlocks are held in virtually the entire
driver. The latest point at which request_firmware could be called was
driver initialization for a particular card. This meant that the earliest
point at which it could be released was driver unload for that card.
The conservative solution for a driver which is lock-happy is to load the
firmware files at module load time and hang on to it until module unload
time. This loses the memory savings benefit but retains the other benefits.
The tg3 is unusual in that some of its firmware was optional. In the case of
tg3 this was pretty easy to handle by converting some #ifdefs to if ()
statements.
---
This was all before request_firmware_nowait was available and functional.
This provides a callback interface instead of a synchronous sleeping
interface. Of course, coding to a callback interface is more invasive
because the existing modules are generally not designed for it. However, it
is preferred long term.
Software suspend (Power Management) with hardware resets is the main function
for which request_firmware_nowait is essential -- but also needed is a
substantial amount of additional kernel infrastructure which isn't present
yet, so it's not as if using request_firmware_nowait will just make software
suspend work. For instance, one thing needed is an event which goes to the
driver *before* the suspend, in response to which the driver grabs the
firmware into RAM, since userspace may not be available at the beginning of
the resume.
I haven't played around a lot with the asynchronous interface. I expect that
it will require essentially the same treatment of drivers as the synchronous
interface, but perhaps with more code rearrangement. After all, you can call
it with a spinlock held, but I believe you still have to get out of the
spinlock in order for the userland hotplug event to run, and therefore in
order for the callback to actually arrive.
I believe there is also a request_firmware_nowait_nohotplug variety, which
simply expects that the firmware has been manually dumped into sysfs before
the driver starts initializing. This might be suitable for some
early-loading modules.
Reply to: