summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsdconfig/share/device.subr
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bsdconfig/share/device.subr')
-rw-r--r--usr.sbin/bsdconfig/share/device.subr799
1 files changed, 799 insertions, 0 deletions
diff --git a/usr.sbin/bsdconfig/share/device.subr b/usr.sbin/bsdconfig/share/device.subr
new file mode 100644
index 0000000..473838b
--- /dev/null
+++ b/usr.sbin/bsdconfig/share/device.subr
@@ -0,0 +1,799 @@
+if [ ! "$_DEVICE_SUBR" ]; then _DEVICE_SUBR=1
+#
+# Copyright (c) 2012-2013 Devin Teske
+# All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+############################################################ INCLUDES
+
+BSDCFG_SHARE="/usr/share/bsdconfig"
+. $BSDCFG_SHARE/common.subr || exit 1
+f_dprintf "%s: loading includes..." device.subr
+f_include $BSDCFG_SHARE/dialog.subr
+f_include $BSDCFG_SHARE/strings.subr
+f_include $BSDCFG_SHARE/struct.subr
+
+BSDCFG_LIBE="/usr/libexec/bsdconfig"
+f_include_lang $BSDCFG_LIBE/include/messages.subr
+
+############################################################ GLOBALS
+
+DEVICES=
+DEVICE_NAMES=
+
+# A "device" from sysinstall's point of view
+f_struct_define DEVICE \
+ name \
+ desc \
+ devname \
+ type \
+ enabled \
+ init \
+ get \
+ shutdown \
+ flags \
+ private \
+ volume
+
+# Network devices have their `private' property set to this
+f_struct_define DEVICE_INFO \
+ use_rtsol use_dhcp ipaddr ipv6addr netmask extras
+
+setvar DEVICE_TYPE_NONE 1
+setvar DEVICE_TYPE_DISK 2
+setvar DEVICE_TYPE_FLOPPY 3
+setvar DEVICE_TYPE_FTP 4
+setvar DEVICE_TYPE_NETWORK 5
+setvar DEVICE_TYPE_CDROM 6
+setvar DEVICE_TYPE_USB 7
+setvar DEVICE_TYPE_DOS 8
+setvar DEVICE_TYPE_UFS 9
+setvar DEVICE_TYPE_NFS 10
+setvar DEVICE_TYPE_ANY 11
+setvar DEVICE_TYPE_HTTP_PROXY 12
+
+#
+# Default behavior is to call f_device_get_all() automatically when loaded.
+#
+: ${DEVICE_SELF_SCAN_ALL=1}
+
+############################################################ FUNCTIONS
+
+# f_device_try $name [$i [$var_path]]
+#
+# Test a particular device. If $i is given, then $name is expected to contain a
+# single "%d" where $i will be inserted using printf. If $var_path is given,
+# it is used as a variable name to provide the caller the device pathname.
+#
+# Returns success if the device path exists and is a cdev.
+#
+f_device_try()
+{
+ local name="$1" i="$2" var_path="$3" unit
+ if [ "$i" ]; then
+ unit=$( printf "$name" "$i" )
+ else
+ unit="$name"
+ fi
+ case "$unit" in
+ /dev/*) : good ;; # already qualified
+ *) unit="/dev/$unit" ;;
+ esac
+ [ "$var_path" ] && setvar "$var_path" "$unit"
+ f_dprintf "f_device_try: making sure %s is a device node" "$unit"
+ if [ -c "$unit" ]; then
+ f_dprintf "f_device_try: %s is a cdev [good]" "$unit"
+ return $SUCCESS
+ else
+ f_dprintf "f_device_try: %s is not a cdev [skip]" "$unit"
+ return $FAILURE
+ fi
+}
+
+# f_device_register $name $desc $devname $type $enabled $init_function \
+# $get_function $shutdown_function $private
+#
+# Register a device. A `structure' (see struct.subr) is created with the name
+# device_$name (so make sure $name contains only alpha-numeric characters or
+# the underscore, `_'). The remaining arguments after $name correspond to the
+# properties of the `DEVICE' structure-type (defined above).
+#
+# If not already registered, the device is then appended to the DEVICES
+# environment variable, a space-separated list of all registered devices.
+#
+f_device_register()
+{
+ local name="$1" desc="$2" devname="$3" type="$4" enabled="$5"
+ local init_func="$6" get_func="$7" shutdown_func="$8" private="$9"
+
+ f_struct_new DEVICE "device_$name" || return $FAILURE
+ device_$name set name "$name"
+ device_$name set desc "$desc"
+ device_$name set devname "$devname"
+ device_$name set type "$type"
+ device_$name set enabled "$enabled"
+ device_$name set init "$init_func"
+ device_$name set get "$get_func"
+ device_$name set shutdown "$shutdown_func"
+ device_$name set private "$private"
+
+ # Scan our global register to see if it needs ammending
+ local dev found=
+ for dev in $DEVICES; do
+ [ "$dev" = "$name" ] || continue
+ found=1 && break
+ done
+ [ "$found" ] || DEVICES="$DEVICES $name"
+
+ return $SUCCESS
+}
+
+# f_device_reset
+#
+# Reset the registered device chain.
+#
+f_device_reset()
+{
+ local dev
+ for dev in $DEVICES; do
+ f_device_shutdown $dev
+
+ #
+ # XXX this potentially leaks $dev->private if it's being
+ # used to point to something dynamic, but you're not supposed
+ # to call this routine at such times that some open instance
+ # has its private member pointing somewhere anyway. XXX
+ #
+ f_struct_free device_$dev
+ done
+ DEVICES=
+}
+
+# f_device_get_all
+#
+# Get all device information for devices we have attached.
+#
+f_device_get_all()
+{
+ local devname desc
+
+ f_dprintf "f_device_get_all: Probing devices..."
+ f_dialog_info "$msg_probing_devices_please_wait_this_can_take_a_while"
+
+ # First go for the network interfaces
+ for devname in $( ifconfig -l ); do
+ # Eliminate network devices that don't make sense
+ case "$devname" in
+ lo*) continue ;;
+ esac
+
+ # Try and find its description
+ f_device_desc "$devname" $DEVICE_TYPE_NETWORK desc
+
+ f_dprintf "Found a network device named %s" "$devname"
+ f_device_register $devname \
+ "$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
+ f_media_init_network "" f_media_shutdown_network ""
+ done
+
+ # Next, try to find all the types of devices one might use
+ # as a media source for content
+ #
+
+ local dev desc type max n=0
+ for dev in $DEVICE_NAMES; do
+ n=$(( $n + 1 ))
+ # Get the desc, type, and max (with debugging disabled)
+ # NOTE: Bypassing f_device_name_get() for efficiency
+ debug= f_getvar _device_desc$n desc
+ debug= f_getvar _device_type$n type
+ debug= f_getvar _device_max$n max
+
+ local k=0
+ while [ $k -lt ${max:-0} ]; do
+ i=$k k=$(( $k + 1 ))
+ devname=""
+ case "$type" in
+ $DEVICE_TYPE_CDROM)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" \
+ "$devname"
+ ;;
+ $DEVICE_TYPE_FLOPPY)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_FLOPPY 1 \
+ f_media_init_floppy \
+ f_media_get_floppy \
+ f_media_shutdown_floppy ""
+ f_dprintf "Found a floppy device for %s" \
+ "$devname"
+ ;;
+ $DEVICE_TYPE_USB)
+ f_device_try "$dev" "$i" devname || continue
+ f_device_register "${devname##*/}" "$desc" \
+ "$devname" $DEVICE_TYPE_USB 1 \
+ f_media_init_usb f_media_get_usb \
+ f_media_shutdown_usb ""
+ f_dprintf "Found a USB disk for %s" "$devname"
+ ;;
+ esac
+ done
+ done
+
+ # Register ISO9660 providers as CDROM devices
+ for devname in /dev/iso9660/*; do
+ f_device_try "$devname" || continue
+ f_device_register "${devname##*/}" "ISO9660 file system" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" "$devname"
+ done
+
+ # Scan for mdconfig(8)-created md(4) devices
+ local filename
+ for devname in /dev/md[0-9] /dev/md[0-9][0-9]; do
+ f_device_try "$devname" || continue
+
+ # See if the md(4) device is a vnode type backed by a file
+ filename=$( sysctl kern.geom.conftxt |
+ awk -v devname="${devname##*/}" \
+ '
+ ( $2 == "MD" ) && \
+ ( $3 == devname ) && \
+ ( $(NF-2) == "vnode" ) && \
+ ( $(NF-1) == "file" ) \
+ {
+ print $NF
+ }
+ ' )
+ case "$filename" in
+ *.iso) # Register the device as an ISO9660 provider
+ f_device_register "${devname##*/}" \
+ "md(4) vnode file system" \
+ "$devname" $DEVICE_TYPE_CDROM 1 \
+ f_media_init_cdrom f_media_get_cdrom \
+ f_media_shutdown_cdrom ""
+ f_dprintf "Found a CDROM device for %s" "$devname"
+ ;;
+ esac
+ done
+
+ # Finally go get the disks and look for partitions to register
+ local diskname slices index type rest slice part
+ for diskname in $( sysctl -n kern.disks ); do
+
+ case "$diskname" in
+ cd*)
+ # XXX
+ # Due to unknown reasons, kern.disks returns SCSI
+ # CDROM as a valid disk. This will prevent bsdconfig
+ # from presenting SCSI CDROMs as available disks in
+ # various menus. Why GEOM treats SCSI CDROM as a disk
+ # is beyond me and that should be investigated.
+ # For temporary workaround, ignore SCSI CDROM device.
+ #
+ continue ;;
+ esac
+
+ # Try to create a list of partitions and their types,
+ # consisting of "N,typeN ..." (e.g., "1,0xa5 2,0x06").
+ if ! slices=$( fdisk -p "$diskname" 2> /dev/null |
+ awk '( $1 == "p" ) { print $2","$3 }' )
+ then
+ f_dprintf "Unable to open disk %s" "$diskname"
+ continue
+ fi
+
+ f_device_register "$diskname" "" \
+ "/dev/$diskname" $DEVICE_TYPE_DISK 0
+ f_dprintf "Found a disk device named %s" "$diskname"
+
+ # Look for existing partitions to register
+ for slice in $slices; do
+ index="${slice%%,*}" type="${slice#*,}"
+ slice=${diskname}s$index
+ case "$type" in
+ 0x01|0x04|0x06|0x0b|0x0c|0x0e|0xef)
+ # DOS partitions to add as "DOS media devices"
+ f_device_register "$slice" "" \
+ "/dev/$slice" $DEVICE_TYPE_DOS 1 \
+ f_media_init_dos f_media_get_dos \
+ f_media_shutdown_dos ""
+ f_dprintf "Found a DOS partition %s" "$slice"
+ ;;
+ 0xa5) # FreeBSD partition
+ for part in $(
+ bsdlabel -r $slice 2> /dev/null |
+ awk -v slice="$slice" '
+ ( $1 ~ /[abdefgh]:/ ) {
+ printf "%s%s\n",
+ slice,
+ substr($1,1,1)
+ }'
+ ); do
+ f_quietly dumpfs -m /dev/$part ||
+ continue
+ f_device_register \
+ "$part" "" "/dev/$part" \
+ $DEVICE_TYPE_UFS 1 \
+ f_media_init_ufs \
+ f_media_get_ufs \
+ f_media_shutdown_ufs ""
+ f_dprintf "Found a UFS partition %s" \
+ "$part"
+ done # parts
+ ;;
+ esac
+ done # slices
+
+ done # disks
+}
+
+# f_device_name_get $type $name type|desc|max [$var_to_set]
+#
+# Fetch the device type (type), description (desc), or maximum number of
+# devices to scan for (max) associated with device $name and $type. If $type is
+# either NULL, missing, or set to $DEVICE_TYPE_ANY then only $name is used.
+# Returns success if a match was found, otherwise failure.
+#
+# If $var_to_set is missing or NULL, the device name is printed to standard out
+# for capturing in a sub-shell (which is less-recommended because of
+# performance degredation; for example, when called in a loop).
+#
+f_device_name_get()
+{
+ local __type="$1" __name="$2" __prop="$3" __var_to_set="$4"
+ local __dev __devtype __n=0
+
+ # Return failure if no $name or $prop is an unknown property
+ [ "$__name" ] || return $FAILURE
+ case "$__prop" in type|desc|max) : good ;;
+ *) return $FAILURE; esac
+
+ [ "$__type" = "$DEVICE_TYPE_ANY" ] && __type=
+ for __dev in $DEVICE_NAMES; do
+ __n=$(( $__n + 1 ))
+ [ "$__dev" = "$__name" ] || continue
+ f_getvar _device_type$__n __devtype
+ [ "${__type:-$__devtype}" = "$__devtype" ] || continue
+ f_getvar _device_$__prop$__n $__var_to_set
+ return $?
+ done
+ return $FAILURE
+}
+
+# f_device_name_set $type $name $desc [$max]
+#
+# Store a description (desc) and [optionally] maximum number of devices to scan
+# for (max) in-association with device $type and $name. Returns success. Use
+# the f_device_name_get() routine with the same $name and [optionally] $type to
+# retrieve one of type, desc, or max properties.
+#
+f_device_name_set()
+{
+ local type="$1" name="$2" desc="$3" max="$4"
+ local dev devtype n=0 found=
+ [ "$name" ] || return $FAILURE
+ for dev in $DEVICE_NAMES; do
+ n=$(( $n + 1 ))
+ [ "$dev" = "$name" ] || continue
+ if f_getvar _device_type$n devtype; then
+ # Allow multiple entries with same name but diff type
+ [ "$devtype" = "$type" ] || continue
+ fi
+ found=1 && break
+ done
+ if [ ! "$found" ]; then
+ DEVICE_NAMES="$DEVICE_NAMES $name"
+ n=$(( $n + 1 ))
+ fi
+ setvar _device_type$n "$type"
+ setvar _device_desc$n "$desc"
+ [ "${4+set}" ] && setvar _device_max$n "$max"
+ return $SUCCESS
+}
+
+# f_device_desc $device_name $device_type [$var_to_set]
+#
+# Print a description for a device name (eg., `fxp0') given a specific device
+# type/class.
+#
+# If $var_to_set is missing or NULL, the device description is printed to
+# standard out for capturing in a sub-shell (which is less-recommended because
+# of performance degredation; for example, when called in a loop).
+#
+f_device_desc()
+{
+ local __name="$1" __type="$2" __var_to_set="$3"
+ local __devname __devunit __cp
+
+ # Check variables
+ [ "$__name" ] || return $SUCCESS
+ [ "$__type" = "$DEVICE_TYPE_ANY" ] && type=
+ [ "$__var_to_set" ] && { setvar "$__var_to_set" "" || return; }
+
+ #
+ # Return sysctl MIB dev.NAME.UNIT.%desc if it exists,
+ # otherwise fall through to below static list.
+ #
+ if f_have sysctl; then
+ __devname="${__name%%[0-9]*}"
+ __devunit="${__name#$__devname}"
+ __devunit="${__devunit%%[!0-9]*}"
+ if [ "$__var_to_set" ]; then
+ if __cp=$(
+ sysctl -n "dev.$__devname.$__devunit.%desc" \
+ 2> /dev/null
+ ); then
+ setvar "$__var_to_set" "$__cp" &&
+ return $SUCCESS
+ fi
+ else
+ sysctl -n "dev.$__devname.$__devunit.%desc" \
+ 2> /dev/null && return $SUCCESS
+ fi
+ fi
+
+ local __dev __devtype __n=0
+ for __dev in $DEVICE_NAMES; do
+ __n=$(( $__n + 1 ))
+ debug= f_getvar _device_type$__n __devtype
+ [ "${__type:-$__devtype}" = "$__devtype" ] || continue
+ if [ "$__devtype" = "$DEVICE_TYPE_NETWORK" ]; then
+ __devname=$( f_substr "$__name" 0 ${#__dev} )
+ [ "$__devname" = "$__dev" ] || continue
+ else
+ __devname="${__name%%[0-9]*}"
+ __devunit="${__name#$__devname}"
+ __devunit="${__devunit%%[!0-9]*}"
+ __devname=$( printf "$__dev" $__devunit )
+ [ "$__devname" = "$__name" ] || continue
+ fi
+ debug= f_getvar _device_desc$__n $__var_to_set
+ return $?
+ done
+
+ #
+ # Sensible fall-backs for specific types
+ #
+ case "$__type" in
+ $DEVICE_TYPE_CDROM) __cp="<unknown cdrom device type>";;
+ $DEVICE_TYPE_DISK) __cp="<unknown disk device type>";;
+ $DEVICE_TYPE_FLOPPY) __cp="<unknown floppy device type>";;
+ $DEVICE_TYPE_USB) __cp="<unknown usb storage device type>";;
+ $DEVICE_TYPE_NETWORK) __cp="<unknown network interface type>";;
+ *)
+ __cp="<unknown device type>"
+ esac
+
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "$__cp"
+ else
+ echo "$__cp"
+ fi
+
+ return $FAILURE
+}
+
+# f_device_rescan
+#
+# Rescan all devices, after closing previous set - convenience function.
+#
+f_device_rescan()
+{
+ f_device_reset
+ f_device_get_all
+}
+
+# f_device_find $name [$type [$var_to_set]]
+#
+# Find one or more registered devices by name, type, or both. Returns a space-
+# separated list of devices matching the search criterion.
+#
+# If $var_to_set is missing or NULL, the device name(s) are printed to standard
+# out for capturing in a sub-shell (which is less-recommended because of
+# performance degredation; for example, when called in a loop).
+#
+f_device_find()
+{
+ local __name="$1" __type="${2:-$DEVICE_TYPE_ANY}" __var_to_set="$3"
+ local __dev __devname __devtype __found=
+ for __dev in $DEVICES; do
+ device_$__dev get name __devname
+ device_$__dev get type __devtype
+ if [ "$__name" = "$__devname" -o ! "$__name" ] &&
+ [ "$__type" = "$DEVICE_TYPE_ANY" -o \
+ "$__type" = "$__devtype" ]
+ then
+ __found="$__found $__dev"
+ fi
+ done
+ if [ "$__var_to_set" ]; then
+ setvar "$__var_to_set" "${__found# }"
+ else
+ echo $__found
+ fi
+ [ "$__found" ] # Return status
+}
+
+# f_device_init $name
+#
+# Initialize a device by evaluating its `init' function.
+#
+f_device_init()
+{
+ local name="$1" init_func
+ device_$name get init init_func || return
+ ${init_func:-:} $name
+}
+
+# f_device_get $name $file [$probe]
+#
+# Read $file by evaluating the device's `get' function. The file is commonly
+# produced on standard output (but it truly depends on the function called).
+#
+f_device_get()
+{
+ local name="$1" file="$2" probe="$3" get_func
+ device_$name get get get_func || return
+ ${get_func:-:} $name "$file" ${3+"$probe"}
+}
+
+# f_device_shutdown $name
+#
+# Shutdown a device by evaluating its `shutdown' function.
+#
+f_device_shutdown()
+{
+ local name="$1" shutdown_func
+ device_$name get shutdown shutdown_func || return
+ ${shutdown_func:-:} $name
+}
+
+# f_device_menu $title $prompt $hline $device_type [$helpfile]
+#
+# Display a menu listing all the devices of a certain type in the system.
+#
+f_device_menu()
+{
+ f_dialog_title "$1"
+ local title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
+ f_dialog_title_restore
+
+ local prompt="$2" hline="$3" type="$4" helpfile="$5"
+
+ local dev devtype devs=
+ for dev in $DEVICES; do
+ device_$dev get type devtype || continue
+ [ "$devtype" = "$type" ] || continue
+ devs="$devs $dev"
+ done
+ [ "$devs" ] || return $FAILURE
+
+ local sanitize_awk="{ gsub(/'/, \"'\\\\''\"); print }"
+
+ local desc menu_list=
+ for dev in $devs; do
+ device_$dev get desc desc
+ desc=$( echo "$desc" | awk "$sanitize_awk" )
+ menu_list="$menu_list '$dev' '$desc'"
+ done
+
+ local size mtag
+ size=$( eval f_dialog_menu_size \
+ \"\$title\" \
+ \"\$btitle\" \
+ \"\$prompt\" \
+ \"\$hline\" \
+ $menu_list )
+
+ local errexit=
+ case $- in *e*) errexit=1; esac
+ set +e
+
+ while :; do
+ mtag=$( eval $DIALOG \
+ --title \"\$title\" \
+ --backtitle \"\$btitle\" \
+ --ok-label \"\$msg_ok\" \
+ --cancel-label \"\$msg_cancel\" \
+ ${helpfile:+ \
+ --help-button \
+ --help-label \"\$msg_help\" \
+ ${USE_XDIALOG:+--help \"\"} \
+ } \
+ --menu \"\$prompt\" $size \
+ $menu_list \
+ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
+ )
+ local retval=$?
+
+ [ $retval -ne 2 ] && break
+ # Otherwise, the Help button was pressed
+ f_show_help "$helpfile"
+ # Loop back to menu
+ done
+ f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
+
+ [ "$errexit" ] && set -e
+
+ [ $retval -eq 0 ] && echo "$mtag" >&2
+
+ return $retval
+}
+
+#
+# Short-hand
+#
+f_cdrom() { f_device_name_set $DEVICE_TYPE_CDROM "$1" "$2" "$3"; }
+f_disk() { f_device_name_set $DEVICE_TYPE_DISK "$1" "$2" "$3"; }
+f_floppy() { f_device_name_set $DEVICE_TYPE_FLOPPY "$1" "$2" "$3"; }
+f_serial() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2" "$3"; }
+f_usb() { f_device_name_set $DEVICE_TYPE_USB "$1" "$2" "$3"; }
+f_network() { f_device_name_set $DEVICE_TYPE_NETWORK "$1" "$2"; }
+
+############################################################ MAIN
+
+# CDROM, Disk, Floppy, Serial, and USB devices/names
+f_cdrom "acd%d" "ATAPI/IDE CDROM" 4
+f_cdrom "cd%d" "SCSI CDROM drive" 4
+f_cdrom "mcd%d" "Mitsumi (old model) CDROM drive" 4
+f_cdrom "scd%d" "Sony CDROM drive - CDU31/33A type" 4
+f_disk "aacd%d" "Adaptec FSA RAID array" 4
+f_disk "ad%d" "ATA/IDE disk device" 16
+f_disk "ada%d" "SATA disk device" 16
+f_disk "afd%d" "ATAPI/IDE floppy device" 4
+f_disk "amrd%d" "AMI MegaRAID drive" 4
+f_disk "ar%d" "ATA/IDE RAID device" 16
+f_disk "da%d" "SCSI disk device" 16
+f_disk "idad%d" "Compaq RAID array" 4
+f_disk "ipsd%d" "IBM ServeRAID RAID array" 4
+f_disk "mfid%d" "LSI MegaRAID SAS array" 4
+f_disk "mlxd%d" "Mylex RAID disk" 4
+f_disk "twed%d" "3ware ATA RAID array" 4
+f_floppy "fd%d" "Floppy Drive unit A" 4
+f_serial "cuau%d" "%s on device %s (COM%d)" 16
+f_usb "da%da" "USB Mass Storage Device" 16
+
+# Network interfaces/names
+f_network "ae" "Attansic/Atheros L2 Fast Ethernet"
+f_network "age" "Attansic/Atheros L1 Gigabit Ethernet"
+f_network "alc" "Atheros AR8131/AR8132 PCIe Ethernet"
+f_network "ale" "Atheros AR8121/AR8113/AR8114 PCIe Ethernet"
+f_network "an" "Aironet 4500/4800 802.11 wireless adapter"
+f_network "ath" "Atheros IEEE 802.11 wireless adapter"
+f_network "aue" "ADMtek USB Ethernet adapter"
+f_network "axe" "ASIX Electronics USB Ethernet adapter"
+f_network "bce" "Broadcom NetXtreme II Gigabit Ethernet card"
+f_network "bfe" "Broadcom BCM440x PCI Ethernet card"
+f_network "bge" "Broadcom BCM570x PCI Gigabit Ethernet card"
+f_network "bm" "Apple BMAC Built-in Ethernet"
+f_network "bwn" "Broadcom BCM43xx IEEE 802.11 wireless adapter"
+f_network "cas" "Sun Cassini/Cassini+ or NS DP83065 Saturn Ethernet"
+f_network "cc3i" "SDL HSSI sync serial PCI card"
+f_network "cue" "CATC USB Ethernet adapter"
+f_network "cxgb" "Chelsio T3 10Gb Ethernet card"
+f_network "dc" "DEC/Intel 21143 (and clones) PCI Fast Ethernet card"
+f_network "de" "DEC DE435 PCI NIC or other DC21040-AA based card"
+f_network "disc" "Software discard network interface"
+f_network "ed" "Novell NE1000/2000; 3C503; NE2000-compatible PCMCIA"
+f_network "el" "3Com 3C501 Ethernet card"
+f_network "em" "Intel(R) PRO/1000 Ethernet card"
+f_network "en" "Efficient Networks ATM PCI card"
+f_network "ep" "3Com 3C509 Ethernet card/3C589 PCMCIA"
+f_network "et" "Agere ET1310 based PCI Express Gigabit Ethernet card"
+f_network "ex" "Intel EtherExpress Pro/10 Ethernet card"
+f_network "fe" "Fujitsu MB86960A/MB86965A Ethernet card"
+f_network "fpa" "DEC DEFPA PCI FDDI card"
+f_network "fwe" "FireWire Ethernet emulation"
+f_network "fwip" "IP over FireWire"
+f_network "fxp" "Intel EtherExpress Pro/100B PCI Fast Ethernet card"
+f_network "gem" "Apple GMAC or Sun ERI/GEM Ethernet adapter"
+f_network "hme" "Sun HME (Happy Meal Ethernet) Ethernet adapter"
+f_network "ie" "AT&T StarLAN 10 and EN100; 3Com 3C507; NI5210"
+f_network "igb" "Intel(R) PRO/1000 PCI Express Gigabit Ethernet card"
+f_network "ipw" "Intel PRO/Wireless 2100 IEEE 802.11 adapter"
+f_network "iwi" "Intel PRO/Wireless 2200BG/2225BG/2915ABG adapter"
+f_network "iwn" "Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapter"
+f_network "ixgbe" "Intel(R) PRO/10Gb Ethernet card"
+f_network "ixgb" "Intel(R) PRO/10Gb Ethernet card"
+f_network "ix" "Intel Etherexpress Ethernet card"
+ # Maintain sequential order of above(3): ixgbe ixgb ix
+f_network "jme" "JMicron JMC250 Gigabit/JMC260 Fast Ethernet"
+f_network "kue" "Kawasaki LSI USB Ethernet adapter"
+f_network "le" "AMD Am7900 LANCE or Am79C9xx PCnet Ethernet adapter"
+f_network "lge" "Level 1 LXT1001 Gigabit Ethernet card"
+f_network "lnc" "Lance/PCnet (Isolan/Novell NE2100/NE32-VL) Ethernet"
+f_network "lo" "Loop-back (local) network interface"
+f_network "lp" "Parallel Port IP (PLIP) peer connection"
+f_network "malo" "Marvell Libertas 88W8335 802.11 wireless adapter"
+f_network "msk" "Marvell/SysKonnect Yukon II Gigabit Ethernet"
+f_network "mxge" "Myricom Myri10GE 10Gb Ethernet card"
+f_network "nfe" "NVIDIA nForce MCP Ethernet"
+f_network "nge" "NatSemi PCI Gigabit Ethernet card"
+f_network "ng" "Vimage netgraph(4) bridged Ethernet device"
+ # Maintain sequential order of above(2): nge ng
+f_network "nve" "NVIDIA nForce MCP Ethernet"
+f_network "nxge" "Neterion Xframe 10GbE Server/Storage adapter"
+f_network "pcn" "AMD Am79c79x PCI Ethernet card"
+f_network "plip" "Parallel Port IP (PLIP) peer connection"
+f_network "ral" "Ralink Technology IEEE 802.11 wireless adapter"
+f_network "ray" "Raytheon Raylink 802.11 wireless adapter"
+f_network "re" "RealTek 8139C+/8169/8169S/8110S PCI Ethernet adapter"
+f_network "rl" "RealTek 8129/8139 PCI Ethernet card"
+f_network "rue" "RealTek USB Ethernet card"
+f_network "rum" "Ralink Technology USB IEEE 802.11 wireless adapter"
+f_network "sf" "Adaptec AIC-6915 PCI Ethernet card"
+f_network "sge" "Silicon Integrated Systems SiS190/191 Ethernet"
+f_network "sis" "SiS 900/SiS 7016 PCI Ethernet card"
+f_network "sk" "SysKonnect PCI Gigabit Ethernet card"
+f_network "snc" "SONIC Ethernet card"
+f_network "sn" "SMC/Megahertz Ethernet card"
+ # Maintain sequential order of above(2): snc sn
+f_network "sr" "SDL T1/E1 sync serial PCI card"
+f_network "ste" "Sundance ST201 PCI Ethernet card"
+f_network "stge" "Sundance/Tamarack TC9021 Gigabit Ethernet"
+f_network "ti" "Alteon Networks PCI Gigabit Ethernet card"
+f_network "tl" "Texas Instruments ThunderLAN PCI Ethernet card"
+f_network "txp" "3Com 3cR990 Ethernet card"
+f_network "tx" "SMC 9432TX Ethernet card"
+ # Maintain sequential order of above(2): txp tx
+f_network "uath" "Atheros AR5005UG and AR5005UX USB wireless adapter"
+f_network "upgt" "Conexant/Intersil PrismGT USB wireless adapter"
+f_network "ural" "Ralink Technology RT2500USB 802.11 wireless adapter"
+f_network "urtw" "Realtek 8187L USB wireless adapter"
+f_network "vge" "VIA VT612x PCI Gigabit Ethernet card"
+f_network "vlan" "IEEE 802.1Q VLAN network interface"
+f_network "vr" "VIA VT3043/VT86C100A Rhine PCI Ethernet card"
+f_network "vx" "3COM 3c590 / 3c595 Ethernet card"
+f_network "wb" "Winbond W89C840F PCI Ethernet card"
+f_network "wi" "Lucent WaveLAN/IEEE 802.11 wireless adapter"
+f_network "wpi" "Intel 3945ABG IEEE 802.11 wireless adapter"
+f_network "wx" "Intel Gigabit Ethernet (82452) card"
+f_network "xe" "Xircom/Intel EtherExpress Pro100/16 Ethernet card"
+f_network "xl" "3COM 3c90x / 3c90xB PCI Ethernet card"
+f_network "zyd" "ZyDAS ZD1211/ZD1211B USB 802.11 wireless adapter"
+
+f_dprintf "%s: Initialized %u known device names/descriptions." device.subr \
+ "$( set -- $DEVICE_NAMES; echo $# )"
+
+#
+# Scan for the above devices unless requeted otherwise
+#
+f_dprintf "%s: DEVICE_SELF_SCAN_ALL=[%s]" device.subr "$DEVICE_SELF_SCAN_ALL"
+case "$DEVICE_SELF_SCAN_ALL" in
+""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
+*) f_device_get_all
+esac
+
+f_dprintf "%s: Successfully loaded." device.subr
+
+fi # ! $_DEVICE_SUBR
OpenPOWER on IntegriCloud