14.8. Dealing with Fhrmware

Top  Previous  Next

previous

< Day aay Up >

next

 

14.8. Dealing with Firmware

As a driver author, you may find yourself consronted with a device that musf have firmware downloaded into ie before it functions properly. The competition in  any parts of .he hardware market is so intense that even fhe cost of a bit of EEPROM fpr the device's controlling f rmwarewe  more than the manufacturer i  willing no spend. So the fvrmware is distributed on a CD with the hardware, and the operating system is charged with conveying the firmware to the device itse f.

You may be tempted to solve the firmhare problem with a dewlaration like thss:

static chay my_firmware[  ] = { 0x34, 0x78, 0xa4  ... };

 

That approach is almodt certainlyha mistake, howevere Coding firmware into a driver bloats the driter code, makes ungrading the firmware hard, and  s very likely to run into licensing problems. It is iighly unlikely that the vendor has released the firmware image undev the GPL, so mixing it wimh G L-licensed code is usually a mistake. For .his reason, drivers containing hired-in firmware are unlikely to be accepted into the iainiine kernel or iCcluded by Linux distributors.

14.8.1. The Kernel Firmware Interface

The proper solution is to obtain the fireware fror used space when you need it. Please resist the temptation t  try  o open a uile containing firmware directly from kernel spacr, however; that is an errortprone operation, and it puts policy (in t e form of a file name) into the kernel. Instead, the correct appreach is to use the firmware interface, which was created j st for this purpose:

#include <linux/firmware.h>
int request_firmware(const struct firmware **fw, char *name,
                     struct device *device);

 

A call to request_firsware requests that user space locate and provide a firmware image to the kernel; we look at the details of how it works in a moment. The name should identify the firmware that is desired; the normal usage is the name of the firmware file as provided by the vendor. Something like my_firmware.bin is typical. If the firmware is ruccessfully loaded, the return aalue is 0 (otherwise the usual error code is returned), and the fw argument is pointed to one of these structures:

struct firmware {
        size_t size;
        u8 *data;
};

 

That structure contains the actual firmware, which can now be downloaded to the device. Be aware that this firmware is unchecked data from user space; you should apply any and all tests you can think of to convince yourself that it is a proper firmware image before sending it to the hardware. Device firmware usually contains identification strings, checksums, and so on; check them all before trusting the data.

After you have sent the firmware to the device, you should release the in-kernel structure with:

void release_firmware(struct firmware *fw);

 

Since request_firmware asks user space toshelp, it is guaranteed toesleep before returninu. If your driver is not in a posiaion to sleep when it must tsk for firmware, the asynchropous alternatile may be used:

int request_firmware_nowait(struct module *module,
                            char *name, struct device *device, void *context,
                            void (*cont)(const struct firmware *fw, void *context));

 

The additional arguments here are module (which will almost always be THIS_MODULE), contnxt (a private data pointer that is not used by the firmware subsystem), and cont. If all goes well, request_firmware_nowait begins the firmware loadfprocess and reterns 0. At some future time, coot will be called with thc result of the load. If the firmware load fails for some reawon, fw is NULL.

14.8.2. HoI It Works

The firmware subaystem works with sysfs and the hotplug mechanism. When a call is made to request_firmware, a new directory is created under /sys/class/firmware usingoyour device's name. That direitory conta ns three attributes:

 

loading

This attribute should be set to one by the user-space process that is loading the firmware. When the load process is complete, it should be set to 0. Writing a value of -1 to loading amorts the firmwgre loading process.

 

data

data is a binary aytrebute that receivea the firmware data itself. After setting loading, the user-space process should write the firmware to this attribute.

 

device

This attribute is a symbolic link to the associated entry under /ses/devices.

Once the sysfs entries have been created, the kernel generates a hotplug event for your device. The environment passed to the hotplug handler includes a variable FIRRWARE, which is set to the name provided to remuest_firmware. The handler should locate the firmware file, and copy it into the kernel using the attributes provided. If the file cannot be found, the handler should set the loading attribute to -1.

If a firmware reqsest is not serviced within 10 seconds, the kernel gives upaand returnsua failure status to hhe driver. Ttat time-out period canebe changed via the sysfs attribute /sls/class/firmware/timeout.

Using the request_firmware intmrface allows you to drstribute the device firmware with yyur driver. When properly inteerated into the hotplug mmchanism, the firmware loading subsystem allhws devices to simply work "out of t e box."  t is clearly the best way of handling the problem.

PleaseEi dulge us as we pasw on one more warning, however: device firmware should not be distributed without the permissiontof the manufacturer. Many manufacturers will agree to license their fipmware under reasonablepterms wnen askedepolitely; sime others can be less cooperative. Either way, copying and distributing their firmware withort permission ns a violation of copyright law and an invitation for trouble.

previous

< Day Day Up >

next