xref: /openbsd/usr.sbin/fw_update/fw_update.sh (revision 91f110e0)
1#!/bin/sh
2
3# $OpenBSD: fw_update.sh,v 1.21 2014/02/23 22:22:16 halex Exp $
4# Copyright (c) 2011 Alexander Hall <alexander@beard.se>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18# This is the list of drivers we should look for
19DRIVERS="acx athn bwi ipw iwi iwn malo otus pgt radeondrm rsu uath
20	upgt urtwn uvideo wpi"
21
22PKG_ADD="pkg_add -I -D repair -DFW_UPDATE"
23PKG_DELETE="pkg_delete -I -DFW_UPDATE"
24
25usage() {
26	echo "usage: ${0##*/} [-adnv] [-p path] [driver ...]" >&2
27	exit 1
28}
29
30verbose() {
31	[ "$verbose" ] && echo "${0##*/}: $@"
32}
33
34setpath() {
35	[ "$path" ] && export PKG_PATH=$path && return
36
37	set -- $(sysctl -n kern.version |
38	    sed 's/^OpenBSD \([0-9]\.[0-9]\)\([^ ]*\).*/\1 \2/;q')
39
40	local version=$1 tag=$2
41
42	[[ $tag == -!(stable) ]] && version=snapshots
43	export PKG_PATH=http://firmware.openbsd.org/firmware/$version/
44}
45
46perform() {
47	if [ "$verbose" ]; then
48		"$@"
49	else
50		"$@" 2>/dev/null
51	fi
52}
53
54all=false
55verbose=
56nop=
57delete=false
58path=
59while getopts 'adnp:v' s "$@" 2>/dev/null; do
60	case "$s" in
61	a)	all=true;;
62	d)	delete=true;;
63	n)	nop=-n;;
64	p)	path=$OPTARG;;
65	v)	verbose=${verbose:--}v;;
66	*)	usage;;
67	esac
68done
69
70shift $((OPTIND - 1))
71
72if $all; then
73	[ $# != 0 ] && usage
74	set -- $DRIVERS
75fi
76
77if $delete && [ $# == 0 ]; then
78	echo "Driver specification required for delete operation" >&2
79	exit 1
80fi
81
82setpath
83
84installed=$(pkg_info -q)
85dmesg=$(cat /var/run/dmesg.boot; echo; dmesg)
86
87install=
88update=
89extra=
90
91if [ $# = 0 ]; then
92	for driver in $DRIVERS; do
93		if print "$installed" | grep -q "^$driver-firmware-" ||
94		    print -r -- "$dmesg" | egrep -q "^$driver[0-9]+ at "; then
95			set -- "$@" $driver
96		fi
97	done
98fi
99
100for driver; do
101	if print "$installed" | grep -q "^${driver}-firmware-"; then
102		update="$update ${driver}-firmware"
103		extra="$extra -Dupdate_${driver}-firmware"
104	elif printf "%s\n" $DRIVERS | fgrep -qx "$driver"; then
105		install="$install ${driver}-firmware"
106	else
107		print -r "${0##*/}: $driver: unknown driver" >&2
108		exit 1
109	fi
110done
111
112if ! $delete && [ -z "$install$update" ]; then
113	verbose "No devices found which need firmware files to be downloaded."
114	exit 0
115elif $delete && [ -z "$update" ]; then
116	verbose "No firmware to delete."
117	exit 0
118fi
119
120$delete || verbose "Path to firmware: $PKG_PATH"
121
122[ "$nop" ] || [ 0 = $(id -u) ] ||
123	{ echo "${0##*/} must be run as root" >&2; exit 1; }
124
125# Install missing firmware packages
126if ! $delete && [ "$install" ]; then
127	verbose "Installing firmware:$update $install."
128	perform $PKG_ADD $nop $verbose $update $install
129fi
130
131# Update or delete installed firmware packages
132if [ "$update" ]; then
133	if $delete; then
134		verbose "Deleting firmware:$update."
135		perform $PKG_DELETE $nop $verbose $update
136	else
137		verbose "Updating firmware:$update."
138		perform $PKG_ADD $extra $nop $verbose -u $update
139	fi
140fi
141