Contents of /alx-src/tags/kernel26-2.6.12-alx-r9/Documentation/firmware_class/README
Parent Directory | Revision Log
Revision 630 -
(show annotations)
(download)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File size: 4378 byte(s)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File size: 4378 byte(s)
Tag kernel26-2.6.12-alx-r9
1 | |
2 | request_firmware() hotplug interface: |
3 | ------------------------------------ |
4 | Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org> |
5 | |
6 | Why: |
7 | --- |
8 | |
9 | Today, the most extended way to use firmware in the Linux kernel is linking |
10 | it statically in a header file. Which has political and technical issues: |
11 | |
12 | 1) Some firmware is not legal to redistribute. |
13 | 2) The firmware occupies memory permanently, even though it often is just |
14 | used once. |
15 | 3) Some people, like the Debian crowd, don't consider some firmware free |
16 | enough and remove entire drivers (e.g.: keyspan). |
17 | |
18 | High level behavior (mixed): |
19 | ============================ |
20 | |
21 | kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device) |
22 | |
23 | userspace: |
24 | - /sys/class/firmware/xxx/{loading,data} appear. |
25 | - hotplug gets called with a firmware identifier in $FIRMWARE |
26 | and the usual hotplug environment. |
27 | - hotplug: echo 1 > /sys/class/firmware/xxx/loading |
28 | |
29 | kernel: Discard any previous partial load. |
30 | |
31 | userspace: |
32 | - hotplug: cat appropriate_firmware_image > \ |
33 | /sys/class/firmware/xxx/data |
34 | |
35 | kernel: grows a buffer in PAGE_SIZE increments to hold the image as it |
36 | comes in. |
37 | |
38 | userspace: |
39 | - hotplug: echo 0 > /sys/class/firmware/xxx/loading |
40 | |
41 | kernel: request_firmware() returns and the driver has the firmware |
42 | image in fw_entry->{data,size}. If something went wrong |
43 | request_firmware() returns non-zero and fw_entry is set to |
44 | NULL. |
45 | |
46 | kernel(driver): Driver code calls release_firmware(fw_entry) releasing |
47 | the firmware image and any related resource. |
48 | |
49 | High level behavior (driver code): |
50 | ================================== |
51 | |
52 | if(request_firmware(&fw_entry, $FIRMWARE, device) == 0) |
53 | copy_fw_to_device(fw_entry->data, fw_entry->size); |
54 | release(fw_entry); |
55 | |
56 | Sample/simple hotplug script: |
57 | ============================ |
58 | |
59 | # Both $DEVPATH and $FIRMWARE are already provided in the environment. |
60 | |
61 | HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/ |
62 | |
63 | echo 1 > /sys/$DEVPATH/loading |
64 | cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data |
65 | echo 0 > /sys/$DEVPATH/loading |
66 | |
67 | Random notes: |
68 | ============ |
69 | |
70 | - "echo -1 > /sys/class/firmware/xxx/loading" will cancel the load at |
71 | once and make request_firmware() return with error. |
72 | |
73 | - firmware_data_read() and firmware_loading_show() are just provided |
74 | for testing and completeness, they are not called in normal use. |
75 | |
76 | - There is also /sys/class/firmware/timeout which holds a timeout in |
77 | seconds for the whole load operation. |
78 | |
79 | - request_firmware_nowait() is also provided for convenience in |
80 | non-user contexts. |
81 | |
82 | |
83 | about in-kernel persistence: |
84 | --------------------------- |
85 | Under some circumstances, as explained below, it would be interesting to keep |
86 | firmware images in non-swappable kernel memory or even in the kernel image |
87 | (probably within initramfs). |
88 | |
89 | Note that this functionality has not been implemented. |
90 | |
91 | - Why OPTIONAL in-kernel persistence may be a good idea sometimes: |
92 | |
93 | - If the device that needs the firmware is needed to access the |
94 | filesystem. When upon some error the device has to be reset and the |
95 | firmware reloaded, it won't be possible to get it from userspace. |
96 | e.g.: |
97 | - A diskless client with a network card that needs firmware. |
98 | - The filesystem is stored in a disk behind an scsi device |
99 | that needs firmware. |
100 | - Replacing buggy DSDT/SSDT ACPI tables on boot. |
101 | Note: this would require the persistent objects to be included |
102 | within the kernel image, probably within initramfs. |
103 | |
104 | And the same device can be needed to access the filesystem or not depending |
105 | on the setup, so I think that the choice on what firmware to make |
106 | persistent should be left to userspace. |
107 | |
108 | - Why register_firmware()+__init can be useful: |
109 | - For boot devices needing firmware. |
110 | - To make the transition easier: |
111 | The firmware can be declared __init and register_firmware() |
112 | called on module_init. Then the firmware is warranted to be |
113 | there even if "firmware hotplug userspace" is not there yet or |
114 | it doesn't yet provide the needed firmware. |
115 | Once the firmware is widely available in userspace, it can be |
116 | removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE). |
117 | |
118 | In either case, if firmware hotplug support is there, it can move the |
119 | firmware out of kernel memory into the real filesystem for later |
120 | usage. |
121 | |
122 | Note: If persistence is implemented on top of initramfs, |
123 | register_firmware() may not be appropriate. |
124 |