[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: