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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6517 - (show 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 #!/bin/sh
2 #
3 # Display driver helper
4 #
5 # Copyright (c) 2010, 2011, 2012 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 # Note that drivers not known by this script are handled normally, i.e.
13 # loaded automatically as udev normally would've.
14 #
15 # 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 # DEBUG_DISPLAY_DRIVER_HELPER=yes
24
25 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
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 # modalias is optional and currently unused
51 local modalias="$2"
52
53 MODOPTIONS=
54
55 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 # 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
70 IS_KMS=1
71 # radeon KMS needs to be loaded before X server
72 NEEDS_LOAD_NOW=1
73 ;;
74 nouveau)
75 # implicitely loaded by X.org
76 check_xorg $name 0 || return 1
77 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 # 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 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 # 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 check_xorg() {
214 local driver="$1"
215 local explicit_only="$2"
216
217 eval local xorg_drivers=\"\$XORG_$driver\"
218 [ -n "$xorg_drivers" ] || xorg_drivers="$driver"
219 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 # 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 }
256
257 # Load the driver for the specified modalias, if configured.
258 # Note: no /usr
259 load_driver() {
260 local modalias="$1"
261 local modulename
262 local load_default=1
263
264 for modulename in $(/sbin/modprobe -Rq "$modalias"); do
265 check_driver "$modulename" "$modalias"
266 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 /sbin/modprobe -b "$modulename" $MODOPTIONS && return 0
288 done
289
290 # no specially handled modules were loaded, so load all modules normally
291 # unless $load_default was set above
292 [ -z "$load_default" ] || /sbin/modprobe -b "$modalias"
293 }
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
301 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 get_hw_display_modaliases() {
312 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 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 for modulename in $(/sbin/modprobe -Rq "$modalias"); do
324 IS_KMS=
325 check_driver "$modulename" "$modalias" || continue
326 [ -n "$IS_KMS" ] && echo $modulename
327 done
328 done
329 }
330
331 setup_boot_kms() {
332 perl -I/usr/lib/libDrakX -MXconfig::various -e 'Xconfig::various::setup_kms()'
333 }
334
335 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 As --check-loaded, and consider ambiguous cases (e.g. nvidia where
387 we can't detect if the loaded driver has the correct version) as
388 failure.
389
390 --setup-boot-kms
391 Set or unset the 'nokmsboot' option as necessary.
392 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 # Extra module options, could be set in check_driver()
425 MODOPTIONS=
426
427 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 --setup-boot-kms)
468 setup_boot_kms
469 ;;
470 *)
471 usage
472 ;;
473 esac

  ViewVC Help
Powered by ViewVC 1.1.30