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

  ViewVC Help
Powered by ViewVC 1.1.30