/[soft]/drakx-kbd-mouse-x11/trunk/tools/display_driver_helper
ViewVC logotype

Annotation of /drakx-kbd-mouse-x11/trunk/tools/display_driver_helper

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3919 - (hide annotations) (download)
Thu Apr 5 02:49:26 2012 UTC (12 years ago) by anssi
File size: 12668 byte(s)
display_driver_helper: drop unused and unuseful --check-initrd option
1 anssi 912 #!/bin/sh
2     #
3     # Display driver helper
4     #
5     # Copyright (c) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi>
6     #
7     # - Load drivers for specified modaliases, skipping disabled display drivers
8     # that would cause conflicts (KMS vs. vesa, KMS vs. proprietary).
9     # - Get information about enabled driver modules
10     # - Check that the loaded modules are correct
11     #
12 anssi 3918 # Note that drivers not known by this script are handled normally, i.e.
13     # loaded automatically as udev normally would've.
14     #
15 anssi 912 # Licensed under terms of GPLv2 or later.
16     #
17     # When updating, check:
18     # - the variables below
19     # - check_driver function
20     # - check_dkms_status function
21     #
22    
23 anssi 3918 # DEBUG_DISPLAY_DRIVER_HELPER=yes
24    
25 anssi 958 if [ -n "$DEBUG_DISPLAY_DRIVER_HELPER" ]; then
26     echo "$(date) $*" >> /dev/ddh_debug
27     exec 2>>/dev/ddh_debug
28     set -x
29     fi
30 anssi 912
31     export LC_ALL=C
32    
33     KMS_DRIVERS="i915 radeon nouveau"
34     # module names at run-time (hence nvidia instead of nvidia*):
35     KNOWN_MODULES="i915|radeon|nouveau|fglrx|nvidia"
36    
37     XORG_i915="intel"
38     CONFLICTS_i915=""
39    
40     XORG_nouveau="nouveau"
41     CONFLICTS_nouveau="nv nvidia"
42    
43     XORG_radeon="ati radeon"
44     CONFLICTS_radeon="fglrx"
45    
46     # Note: no /usr
47     # See end of script for descriptions of global variables.
48     check_driver() {
49     local name="$1"
50     case "$name" in
51     i915)
52     # implicitely loaded by X.org
53     check_xorg $name 0 || return 1
54     IS_KMS=1
55     ;;
56     radeon)
57     # implicitely loaded by X.org
58     check_xorg $name 0 || return 1
59 anssi 997 # Do not load if the proprietary driver is temporarily disabled
60     # on a PowerXpress system.
61     # TODO: this check could be omitted if radeon was explicitely
62     # specified in xorg.conf - but that is only known by check_xorg.
63     check_gl /etc/fglrx/pxpress-free.ld.so.conf && return 1
64 anssi 912 IS_KMS=1
65 anssi 2244 # radeon needs to be loaded before X server
66 anssi 912 NEEDS_LOAD_NOW=1
67     ;;
68     nouveau)
69     # these KMS drivers require an explicit directive in xorg.conf
70     check_xorg $name 1 || return 1
71     IS_KMS=1
72     ;;
73     fglrx)
74     check_xorg fglrx 1 || return 1
75     check_dkms fglrx || return 1
76     ;;
77     nvidia)
78     # manually installed driver or a call from check_loaded()
79     UNSURE=1
80     check_xorg nvidia 1 || return 1
81     ;;
82     nvidiafb)
83     # this is only reached if nvidiafb is manually unblacklisted
84     return 2
85     ;;
86     nvidia*)
87     [ "$name" = "nvidia_current" ] && name=nvidia-current
88     # there are multiple co-installable driver versions, so check
89     # the active alternative as well
90     check_gl /etc/$name/ld.so.conf || return 1
91     check_xorg nvidia 1 || return 1
92     check_dkms $name || return 1
93     ;;
94     *)
95     # unknown, will be loaded only if no known drivers were found
96     return 2
97     ;;
98     esac
99     return 0
100     }
101    
102     # Return success if there is no new pending DKMS build (needed to disallow
103     # speedboot on very early boot).
104     # Previously failed build or a missing module is counted as no pending build.
105     # Note: no /usr
106     check_dkms_status() {
107     [ -e /etc/alternatives/gl_conf ] || return 0
108     # return fast for non-DKMS
109     check_gl /etc/ld.so.conf.d/GL/standard.conf && return 0
110    
111     local active="$(ls -l /etc/alternatives/gl_conf | awk '{ print $NF }')"
112    
113     local modname=
114    
115     case $active in
116     /etc/nvidia*/ld.so.conf)
117     modname="nvidia${active#*nvidia}"
118     modname="${modname%/*}"
119     ;;
120     /etc/ld.so.conf.d/GL/ati.conf)
121     modname="fglrx"
122     ;;
123     *)
124     # Unknown DKMS-looking driver,
125     # allow speedboot.
126     return 0
127     ;;
128     esac
129     check_dkms "$modname" 1
130     }
131    
132     # Check if all loaded kernel modules have correct xorg.conf
133     check_loaded() {
134     for module in $(grep -oE "^($KNOWN_MODULES) " /proc/modules); do
135 anssi 961 # try to unload the driver in case it is not in use before bailing
136     check_driver "$module" || rmmod "$module" &>/dev/null || return 1
137 anssi 912 done
138     return 0
139     }
140    
141     # Check that specified DKMS driver is not queued for build for the current
142     # kernel. Used to check if we 1) should disable speedboot for this boot
143     # (--check-dkms-status), and 2) if should should load the currently
144     # existing driver (--load). Doing otherwise might cause us to load a wrong old
145     # version of the driver that had been installed using e.g. binary DKMS
146     # packages.
147     # Note: no /usr
148     check_dkms() {
149     local driver="$1"
150     local force="$2"
151    
152     # If called from DKMS itself or we are not in rc.sysinit anymore,
153     # there are no pending builds.
154     if [ -z "$force" ]; then
155     [ "$DKMS_AUTOLOAD_MODULE" = "$driver" ] && return 0
156     [ -z "$STARTUP" ] && [ ! -f "/dev/.in_sysinit" ] && return 0
157     fi
158    
159     local found=
160     local uname_r="$(uname -r)"
161    
162     for dir in /var/lib/dkms/$driver/*; do
163     [ -e "$dir" ] || return 0 # no module, no build; or no /var
164     [ -L "$dir" ] && continue # not a module version
165     found=1 # module version found
166     [ -e "$dir/$uname_r" ] && return 0
167     [ -e "/var/lib/dkms-binary/$driver/$(basename "$dir")/$uname_r" ] && return 0
168    
169     if [ -e "$dir/build/make.log" ]; then
170     # Build has failed for some kernel, check if it is this one.
171     # If so, there is no point in returning 1.
172     grep -q "^DKMS make\.log.* $uname_r " && return 0
173     fi
174     done
175    
176     # if module versions were found but none were built for this kernel, return 1
177     [ -n "$found" ] && return 1 || return 0
178     }
179    
180     # Note: no /usr
181     check_gl() {
182     local alt_inode="$(stat -L -c%i $1 2>/dev/null)"
183     [ -n "$alt_inode" ] || return 1
184     [ -n "$GL_INODE" ] || GL_INODE="$(stat -L -c%i /etc/alternatives/gl_conf 2>/dev/null)"
185     [ "$alt_inode" = "$GL_INODE" ] || return 1
186     return 0
187     }
188    
189     # Note: no /usr
190     get_xorg_drivers() {
191     if [ -z "$XORG_DRIVERS" ]; then
192     XORG_DRIVERS="$(cat /etc/X11/xorg.conf /etc/X11/xorg.conf.d/*.conf 2>/dev/null |
193     awk -F'"' -vORS=' ' -vIGNORECASE=1 '
194     /^[[:space:]]+*section[[:space:]]+"device"/ { device=1 }
195     /endsection/ { device=0 }
196     /^[[:space:]]*driver[[:space:]]*".*"/ { if (device) drivers[$2]=$2 }
197     END { for (driver in drivers) print driver }
198     ')"
199     [ -n "$XORG_DRIVERS" ] || XORG_DRIVERS="-"
200     fi
201     }
202    
203     # Note: no /usr
204 anssi 3918 # parameter 1: KMS module or xorg driver
205     # parameter 2: 1 - check if the driver is explicitely enabled
206     # 0 - check only for conflicts
207 anssi 912 check_xorg() {
208     local driver="$1"
209     local explicit_only="$2"
210    
211     eval local xorg_drivers=\"\$XORG_$driver\"
212 anssi 959 [ -n "$xorg_drivers" ] || xorg_drivers="$driver"
213 anssi 912 eval local conflicts=\"\$CONFLICTS_$driver\"
214    
215     get_xorg_drivers
216    
217     conflict_found=
218     for enabled_driver in $XORG_DRIVERS; do
219     for xorg_driver in $xorg_drivers; do
220     [ "$enabled_driver" = "$xorg_driver" ] && return 0
221     done
222    
223     # if the X.org driver can be loaded implicitely, check that
224     # there are no conflicting drivers that override the driver
225     if [ "$explicit_only" = "0" -a -z "$conflict_found" ]; then
226     for conflict in vesa $conflicts; do
227     if [ "$enabled_driver" = "$conflict" ]; then
228     conflict_found=1
229     continue 2
230     # continue loop to check for an explicit load
231     fi
232     done
233     fi
234     done
235    
236     # in case of a conflict, do not load the module
237     [ -n "$conflict_found" ] && return 1
238    
239     # no driver is selected - don't load if explicit_only is 1
240     [ "$explicit_only" = "1" ] && return 1
241    
242 anssi 1681 # implicit load allowed; only load if there is evidence that this is
243     # not a live cd or similar with automatic configuration occurring later
244     # in the boot process (which might configure a driver conflicting with
245     # the implicit driver, e.g. a proprietary one)
246     # TODO: Could this be replaced with a more robust check?
247     [ -e "/etc/X11/xorg.conf" ] || [ -e "/etc/sysconfig/harddrake2/kernels" ] ||
248     [ -e "/etc/sysconfig/harddrake2/xorg" ] || [ -e "/boot/grub/menu.lst" ]
249 anssi 912 }
250    
251     # Load the driver for the specified modalias, if configured.
252     # Note: no /usr
253     load_driver() {
254 anssi 3918 local modalias="$1"
255 anssi 912 local modulename
256     local load_default=1
257    
258 anssi 3918 for modulename in $(/sbin/modprobe -Rq "$modalias"); do
259 anssi 912 check_driver "$modulename"
260     case $? in
261     1) # a driver which needs handling by this script matches
262     # the modalias, but was not configured - do not run
263     # the generic modprobe if no other drivers are
264     # configured either
265     load_default=
266     continue
267     ;;
268     2) continue
269     ;;
270     esac
271    
272     if [ -n "$IS_KMS" ]; then
273     grep -q "^$modulename " /proc/modules && return 0
274     echo "$modulename" > /dev/.late_kms 2>/dev/null
275     # If NEEDS_LOAD_NOW is not set and plymouth is running,
276     # skip loading the driver to avoid quitting plymouth.
277     # The driver will be loaded later by X server itself.
278     [ -z "$NEEDS_LOAD_NOW" ] && /bin/plymouth --ping 2>/dev/null && return 0
279     /bin/plymouth quit 2>/dev/null
280     fi
281     /sbin/modprobe -b "$modulename" && return 0
282     done
283    
284     # no specially handled modules were loaded, so load all modules normally
285     # unless $load_default was set above
286 anssi 3918 [ -z "$load_default" ] || /sbin/modprobe -b "$modalias"
287 anssi 912 }
288    
289     is_kms_allowed() {
290     for driver in $KMS_DRIVERS; do
291     # Check all drivers for conflicts only.
292     check_xorg $driver 0 || return 1
293     done
294     return 0
295     }
296    
297     get_initrd_kms_drivers() {
298     local initrd="$1"
299    
300     local kms_drivers="$(echo "$KMS_DRIVERS" | tr " " "|")"
301     zcat "$initrd" | cpio -t --quiet | sed -nr "s,.*/($kms_drivers)\.ko.*$,\1,p"
302     }
303    
304     get_active_kms_drivers() {
305     local kms_drivers=
306     for device in $(grep -l 0x03 /sys/bus/pci/devices/0000\:0*/class); do
307     [ -e "$device" ] || continue
308     device="$(dirname $device)"
309     [ -f "$device/modalias" ] || continue
310     modalias="$(cat "$device/modalias")"
311 anssi 2245 for modulename in $(/sbin/modprobe -Rq "$modalias"); do
312 anssi 912 IS_KMS=
313     check_driver "$modulename" || continue
314     [ -n "$IS_KMS" ] && echo $modulename
315     done
316     done
317     }
318    
319     usage() {
320     cat <<EOF
321     Usage: $0 action [arguments]
322    
323     Known actions:
324    
325     --load MODALIAS
326     Load drivers matching MODALIAS, checking that they are enabled and
327     configured.
328    
329     --load-dkms-autoload MODNAME MODALIAS
330     Same as --load, but assume MODNAME is built and correct so that
331     checking dkms status is unnecessary.
332    
333     --is-disabled MODNAME
334     Checks whether the driver corresponding to MODNAME is disabled (e.g.
335     a conflicting driver is configured, etc.). Unknown MODNAMEs are
336     considered not disabled.
337    
338     --is-enabled-kms MODNAME
339     Checks whether the driver corresponding to MODNAME is enabled and
340     MODNAME is a known KMS module. Note that drivers may be enabled even
341     if there is no such hardware. This just checks that there are
342     no conflicting drivers in use etc.
343    
344     --is-kms-allowed
345     Checks whether it is ok to load KMS drivers in initrd. This returns
346     a failure when a conflicting driver is set up (vesa or a proprietary
347     one).
348    
349     --get-all-kms-drivers
350     Get a list of the known KMS drivers.
351    
352     --get-active-kms-drivers
353     Get a list of the known KMS drivers which are enabled and the hardware
354     is present.
355    
356     --get-initrd-kms-drivers INITRD
357     Get a list of the known KMS drivers in initrd INITRD.
358    
359     --check-dkms-status
360     Checks if there are no pending DKMS builds for the currently enabled
361     drivers.
362    
363     --check-loaded
364     Checks that there are no disabled drivers loaded.
365    
366     --check-speedboot
367     Does --check-dkms-status and --check-loaded.
368    
369     --check-loaded-strict
370 anssi 3918 As --check-loaded, and consider ambiguous cases (e.g. nvidia where
371 anssi 912 we can't detect if the loaded driver has the correct version) as
372     failure.
373     EOF
374     }
375    
376     # clear global variables
377    
378     # cache for check_gl()
379     GL_INODE=
380    
381     # cache for check_xorg()
382     XORG_DRIVERS=
383    
384     # The driver is a KMS enabled driver. This will cause the script to quit
385     # plymouth when a driver is loaded by --load and NEEDS_LOAD_NOW below is set.
386     # This is done as plymouth is still attached to the default framebuffer (the
387     # issues caused by not doing this don't seem to be fatal, though, but the
388     # display may be lost completely until plymouth eventually stops).
389     # There is no option in plymouth to "reload" a driver, it expects any KMS
390     # driver to be loaded be before starting it.
391     IS_KMS=
392    
393     # This KMS driver needs to be loaded before X server starts, so load it now
394     # even if we have to shut down plymouth (see above).
395     NEEDS_LOAD_NOW=
396    
397     # dkms module that was built when calling from DKMS
398     DKMS_AUTOLOAD_MODULE=
399    
400     # Set by check_loaded() when it can't be sure that the correct driver is loaded
401     # (e.g. in case of the multiple proprietary nvidia drivers which all identify as
402     # "nvidia" in loaded modules list).
403     UNSURE=
404    
405     case "$1" in
406     --load)
407     load_driver "$2"
408     ;;
409     --load-dkms-autoload)
410     DKMS_AUTOLOAD_MODULE="$2"
411     load_driver "$3"
412     ;;
413     --is-disabled)
414     check_driver "$2"
415     [ $? -eq 1 ]
416     # unknown (2) are not considered disabled :)
417     ;;
418     --is-enabled-kms)
419     check_driver "$2" && [ -n "$IS_KMS" ]
420     ;;
421     --is-kms-allowed)
422     is_kms_allowed
423     ;;
424     --check-dkms-status)
425     check_dkms_status
426     ;;
427     --get-all-kms-drivers)
428     echo $KMS_DRIVERS
429     ;;
430     --get-active-kms-drivers)
431     get_active_kms_drivers
432     ;;
433     --get-initrd-kms-drivers)
434     get_initrd_kms_drivers "$2"
435     ;;
436     --check-loaded)
437     check_loaded
438     ;;
439     --check-loaded-strict)
440     check_loaded && [ -z "$UNSURE" ]
441     ;;
442     --check-speedboot)
443     check_dkms_status && check_loaded
444     ;;
445     *)
446     usage
447     ;;
448     esac

  ViewVC Help
Powered by ViewVC 1.1.30