[ivtv-devel] ivtv firmware not loading using static /dev

Andy Walls awalls at md.metrocast.net
Thu Apr 8 02:05:53 CEST 2010


On Tue, 2010-04-06 at 04:21 +0000, Rick Seiler wrote:
> Hauppage PVR 150 or 250
> 
> If I create a static /dev or use devtmpfs (to create /dev), firmware
> will not load (cannot find /dev/video0)
> 
> If I run udev_start, even with a devtmpfs /dev, then the firmware
> loads and the card is usable
> 
> What am I missing? What magic is udev doing to allow the firmware to
> load?

udev is actually loading the firmware for you.

The kernel firmware loading mechanism requires *some* userspace
application to load firmware.  It doesn't have to be udev, but some
application that responds to the request from the kernel.


> Tried kernel versions 2.6.32, 2.6.33, 2.6.33-rcx to no avail.
> 
> Please advise. I will provide any additional details or debugs if
> necessary.

(cutting from a previous private email I sent once...)

OK. First a conceptual idea of the process of loading firmware :

1. driver calls request_firmware(&fw_entry, $FIRMWARE, device)

2. kernel creates special nodes under /sys/.../firmware/...
        for the request

3. kernel then
        a. sets up environment variables and spawns the userspace
           process named by
                cat /proc/sys/kernel/hotplug
          (which is usually '/sbin/hotplug' at early boot, but is
           usually cleared out by some other process later)

        b. sends the environment over a netlink socket to a userspace
           process (like udev) waiting for events.

        The event & enviroment will contain something like:

        KERNEL[1263675231.515769] add      /devices/pci0000:00/0000:00:02.0/0000:02:00.0/i2c-adapter/i2c-6/6-0044/firmware/6-0044 (firmware)
        UDEV_LOG=3
        ACTION=add
        DEVPATH=/devices/pci0000:00/0000:00:02.0/0000:02:00.0/i2c-adapter/i2c-6/6-0044/firmware/6-0044
        SUBSYSTEM=firmware
        FIRMWARE=v4l-cx23885-avcore-01.fw
        SEQNUM=1819

        
4. userspace process lets the kernel know the firmware load is
   happening:
        echo 1 > /sys/.../firmware/.../loading

5. kernel discards any previous partial load.

6. userspace process writes the appropriate_firmware_image to
        /sys/.../firmware/.../data

7. kernel grows a buffer in PAGE_SIZE increments to hold the image as
           it comes in.

8. userspace lets the kernel know the firmware load is finished:
        echo 0 > /sys/.../firmware/.../loading

9. driver's request_firmware() returns and the driver has the firmware
            image in fw_entry->{data,size}. If something went wrong
            request_firmware() returns non-zero and fw_entry is set to
            NULL.

10. driver code calls release_firmware(fw_entry)
          releasing the firmware image


So you need to check that

1. Check that your kernel was built with CONFIG_FW_LOADER in kernel (the
default) or as a module.  Also that CONFIG_HOTPLUG support was enabled
too.  This is the option that enables the kernel to use userspace
firmware loading. 

2. Check that udev is running or that you have a process
like /sbin/hotplug named in /proc/sys/kernel/hotplug, and that
the /sbin/hotplug script or executable is configured to find the
firmware where you put it.


If you have udev running, you can monitor the many events it receives
during a module load:

# udevadm monitor --kernel --udev --property 2>&1 > /tmp/udev-load.txt &
# modprobe cx23885
# fg
^C
# less /tmp/udev-load.txt

Search for FIRMWARE or firmware.  (Or you can just look at the one
example event I gave earlier.)

Then read

         /lib/udev/firmware.sh

to see what the firmware loading script does.  It lists all the possible
firmware drectories udev cares about at the very top of the file.


(cutting from yet another private email talking about using BusyBox
invoked as mdev, instead of udev...)

>From my research (not experience), mdev should be able to load firmware
as the kernel hotplug userspace component.  You need to check that:

a. the firmware is in /lib/firmware
b. BusyBox was built with ENABLE_FEATURE_MDEV_LOAD_FIRMWARE enabled
(when busyBox is invoked as "mdev" it performs the mdev functionality).


No special changes need to be made to /etc/mdev.conf

(I also read that /dev needs to be mounted this way:
        mount -t tmpfs mdev /dev
but I suspect that is only if mdev is used to create device nodes
dynamically.  I suspect you may be already set up properly anyway.)


The /sys entries that get created for hotplug firmware loading have a 60
second life time by default in my kernels.  The nodes will disappear if
the firmware load doesn't complete in that time.

Note that the loading and data nodes will show up under a hotplug
specific path

        /sys/$DEVPATH/loading
        /sys/$DEVPATH/data

where $DEVPATH is provided by the kernel in the hotplug event
notification.  In my previous example for my CX23885 based card:

        DEVPATH=/devices/pci0000:00/0000:00:02.0/0000:02:00.0/i2c-adapter/i2c-6/6-0044/firmware/6-0044

so you're generally not going to predict these things ahead of time.

You could change the hotplug agent the kernel calls from /sbin/mdev to
something else temporarily like a script to log the environment or
actually do the firmware load, but I don't think you'll find any
surprises.

I suspect you'll need to add debug to mdev (aka BusyBox) to see if it is
trying to load the firmware.  Note that the kernel executes the hotplug
user agent with no file descriptors open.  You have to open
probably /dev/console as stdout and stderr to print out from withing
mdev.

Anyway, see this whole thread:
http://www.mail-archive.com/busybox@busybox.net/msg04749.html



Regards,
Andy





More information about the ivtv-devel mailing list