[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#725714: Partial fix using hw-setup for the missing firmware problem in d-i?



I noticed this bug was mentioned as a regression in the Jessie
installer, and thought I should have a look at how this could be
improved from the hw-detect side.

The following patch replaces the code looking in
/dev/.udev/firmware-missing and /run/udev/firmware-missing for firmware
wanted by the kernel with code looking for firmware listed in the
meta-info of loaded modules.  It will solve the problem for at least
some kernel modules, but not the class of modules refusing to load if
their firmware files are missing.

Perhaps something do use while we wait for more information from the
kernel side?

The patch is only partly tested on the command line inside d-i, and is
based on the isenkram code, but rewritten to avoid awk, as awk is not
available in d-i.  I can brush it up if we decide to go in this
direction.

diff --git a/check-missing-firmware.sh b/check-missing-firmware.sh
index 60c6ff4..77a670e 100755
--- a/check-missing-firmware.sh
+++ b/check-missing-firmware.sh
@@ -2,7 +2,6 @@
 set -e
 . /usr/share/debconf/confmodule
 
-MISSING='/dev/.udev/firmware-missing /run/udev/firmware-missing'
 DENIED=/tmp/missing-firmware-denied
 
 if [ "x$1" = "x-n" ]; then
@@ -67,61 +66,29 @@ check_missing () {
 	# Give modules some time to request firmware.
 	sleep 1
 	
-	modules=""
-	files=""
-	for missing_dir in $MISSING
-	do
-		if [ ! -d "$missing_dir" ]; then
-			log "$missing_dir does not exist, skipping"
-			continue
-		fi
-		for file in $(find $missing_dir -type l); do
-			# decode firmware filename as encoded by
-			# udev firmware.agent
-			fwfile="$(basename $file | sed -e 's#\\x2f#/#g')"
-			
-			# strip probably nonexistant firmware subdirectory
-			devpath="$(readlink $file | sed 's/\/firmware\/.*//')"
-			# the symlink is supposed to point to the device in /sys
-			if ! echo "$devpath" | grep -q '^/sys/'; then
-				devpath="/sys$devpath"
-			fi
-
-			module=$(get_module "$devpath")
-			if [ -z "$module" ]; then
-				log "failed to determine module from $devpath"
-				continue
-			fi
-
-			rm -f "$file"
-
-			if grep -q "^$fwfile$" $DENIED 2>/dev/null; then
-				continue
-			fi
-			
-			files="$fwfile${files:+ $files}"
-
-			if [ "$module" = usbcore ]; then
-				# Special case for USB bus, which puts the
-				# real module information in a subdir of
-				# the devpath.
-				for dir in $(find "$devpath" -maxdepth 1 -mindepth 1 -type d); do
-					module=$(get_module "$dir")
-					if [ -n "$module" ]; then
-						modules="$module${modules:+ $modules}"
-					fi
-				done
-			else
-				modules="$module${modules:+ $modules}"
-			fi
-		done
-	done
-
+        # Workaround for bug #725714, the kernel and udev no longer
+        # let us know via /dev/.udev/firmware-missing and
+        # /run/udev/firmware-missing which firmware files the kernel
+        # drivers look for.  This approach will only find firmware for
+        # the loaded kernel modules.  Modules refusing to
+        # register/load when the firmware is missing will be missed.
+        for fwfile in $(for module in $(cut -d" " -f1 /proc/modules); do modinfo $module | grep ^firmware:|cut -d: -f2; done); do 
+            if [ ! -e /lib/firmware/$fwfile ] ; then
+
+                if grep -q "^$fwfile$" $DENIED 2>/dev/null; then
+                    continue
+                fi
+
+                files="${files:+$files }$fwfile"
+                modules="$module${modules:+ $modules}"
+            fi
+        done
+	
 	if [ -n "$modules" ]; then
 		log "missing firmware files ($files) for $modules"
 		return 0
 	else
-		log "no missing firmware in $MISSING"
+		log "no missing firmware for any loaded kernel module"
 		return 1
 	fi
 }

-- 
Happy hacking
Petter Reinholdtsen


Reply to: