#!/bin/sh -
#
# Generated from:
#       NetBSD: MAKEDEV.awk,v 1.21 2010/03/30 07:30:03 mrg Exp
#       NetBSD: MAKEDEV.tmpl,v 1.151.2.2 2012/05/30 08:06:26 sborrill Exp
#       NetBSD: etc.vax/MAKEDEV.conf,v 1.13 2011/10/12 17:03:49 njoly Exp
#
# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
# 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 NETBSD FOUNDATION, INC. 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 FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, 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.
#
#
###########################################################################
#
#
# Device "make" file.  Valid special arguments:
#       all     makes all known devices, including local devices.
#               Tries to make the 'standard' number of each type.
#       init    A set of devices that is used for MFS /dev by init.
#               May be equal to "all".
#       floppy  devices to be put on install floppies
#       ramdisk devices to be put into INSTALL kernel ramdisks.
#       std     standard devices
#       local   configuration specific devices
#       wscons  make wscons devices
#       usbs    make USB devices
#       isdns   make ISDN devices
#

#
# NOTE:
#
# * MAKEDEV is used both as a standalone script (via "sh ./MAKEDEV
#   all" or similar), and as a function library for MAKEDEV.local (via
#   "MAKEDEV_AS_LIBRARY=1 . MAKEDEV").  Because of this, the script
#   should consist almost entirely of function definitions, apart from a
#   few lines right at the end.
#
# * MAKEDEV may be executed in an environment that is missing some
#   common commands.  For example, it may be executed from a minimal
#   system used during installation, or it may be executed early in the
#   boot sequence before most file systems have been mounted.  It may
#   also be executed in a cross-build environment on a non-NetBSD host.
#

usage()
{
        cat 1>&2 << _USAGE_
Usage: ${0##*/} [-fMsu] [-m mknod] [-p pax] [-t mtree] special [...]
        Create listed special devices.  Options:
        -f              Force permissions to be updated on existing devices.
        -M              Create memory file system.
        -m mknod        Name of mknod(8) program.  [\$TOOL_MKNOD or mknod]
        -p pax          Name of pax(1) program.  [\$TOOL_PAX or pax]
        -s              Generate mtree(8) specfile instead of creating devices.
        -t mtree        Name of mtree(8) program.  [\$TOOL_MTREE or mtree]
        -u              Don't re-create devices that already exist.

_USAGE_
        exit 1
}

# zeropad width number
#       display number with a zero (`0') padding of width digits.
#
zeropad()
{
        case $(($1 - ${#2})) in
        5)      echo 00000$2;;
        4)      echo 0000$2;;
        3)      echo 000$2;;
        2)      echo 00$2;;
        1)      echo 0$2;;
        0)      echo $2;;
        *)      die "bad padding" ;;
        esac
}

# hexprint number
#       display (base10) number as hexadecimal
#
hexprint()
{
        val="$(($1 + 0))"
        hex=
        set -- 0 1 2 3 4 5 6 7 8 9 a b c d e f
        while [ "$val" -gt 0 ]; do
                eval hex=\$$(($val % 16 + 1))\$hex
                val="$(($val / 16))"
        done
        echo "${hex:-0}"
}

# linecount multiline_string
#       count the number of lines in the string
#
linecount()
{
        local IFS='
' # just a newline, no other white space between the quotes
        set -- $1
        echo $#
}

# nooutput -12 cmd [args...]
#       run a command with stdout and/or stderr ignored.
#       "nooutput -1 cmd" is like "cmd >/dev/null";
#       "nooutput -2 cmd" is like "{ cmd ; } 2>/dev/null";
#       "nooutput -12 cmd" is like "{ cmd ; } >/dev/null 2>&1";
#       except they should work even if /dev/null doesn't [yet] exist.
#
#       The "{...}" wrapper used in cases where stderr is redirected
#       serves to capture shell error messages such as "cmd: not found".
#
nooutput()
{
        local flags="$1" ; shift
        local junk
        case "$flags" in
        "-1")   junk="$( "$@" )" ;;
        "-2")   ( exec 4>&1 ; junk="$( { "$@" ; } 2>&1 1>&4 )" ) ;;
        "-12")  junk="$( { "$@" ; } 2>&1 )" ;;
        *)      warn "Incorrect use of nooutput" ;;
        esac
}

# check_pax path_to_pax
#       Check whether pax exists and supports the command line options
#       and input format that we will want to use.
#
check_pax()
{
        local pax="$1"
        echo ". type=dir optional" | nooutput -12 "${pax}" -r -w -M -pe .
}

# check_mtree path_to_mtree
#       Check whether mtree exists and supports the command line options
#       and input format that we will want to use.
#
check_mtree()
{
        local mtree="$1"
        echo ". type=dir optional" | nooutput -12 "${mtree}" -e -U
}

# setup args...
#       Parse command line arguments, exit on error.
#       Callers should shift $((OPTIND - 1)) afterwards.
#
setup()
{
        PATH=/sbin:/usr/sbin:/bin:/usr/bin:/rescue

        : ${TOOL_MKNOD:=mknod}
        : ${TOOL_MTREE:=mtree}
        : ${TOOL_PAX:=pax}
        status=0
        do_create_mfs=false
        do_force=false
        do_mknod=false
        do_pax=false
        do_mtree=false
        do_redirect=false
        do_specfile=false
        do_update=false
        opts=
        while getopts Mfm:p:st:u ch; do
                # Note that $opts is only for options pased through to
                # MAKEDEV.local, not for all options.
                case ${ch} in
                M)
                        # "-M" sets do_create_mfs;
                        # "-M -M" is for use from init(8), and sets do_redirect
                        do_redirect=$do_create_mfs
                        do_create_mfs=true
                        ;;
                f)      do_force=true
                        opts="${opts} -f"
                        ;;
                m)      TOOL_MKNOD=${OPTARG}
                        do_mknod=true
                        opts="${opts} -m ${OPTARG}"
                        ;;
                p)      TOOL_PAX="${OPTARG}"
                        if check_pax "${TOOL_PAX}"; then
                                do_pax=true
                                # do not add this to $opts; we will later
                                # add "-s" instead.
                        else
                                warn "Ignored -p option:" \
                                        "${TOOL_PAX} is missing or broken"
                                do_mknod=true
                        fi
                        ;;
                s)      do_specfile=true
                        opts="${opts} -s"
                        ;;
                t)      TOOL_MTREE="${OPTARG}"
                        if check_mtree "${TOOL_MTREE}"; then
                                do_mtree=true
                                # do not add this to $opts; we will later
                                # add "-s" instead.
                        else
                                warn "Ignored -t option:" \
                                        "${TOOL_MTREE} is missing or broken"
                                do_mknod=true
                        fi
                        ;;
                u)
                        do_update=true
                        opts="${opts} -u"
                        ;;
                *)      usage ;;
                esac
        done

        shift $((${OPTIND} - 1))
        [ $# -gt 0 ] || usage

        u_root="0"
        u_uucp="66"
        g_kmem="2"
        g_ntpd="15"
        g_operator="5"
        g_wheel="0"
        dialin=0
        dialout=524288
        callunit=262144

        # only allow read&write for owner by default
        umask 077

        # Set fdesc_mounted=true if the fdesc file system is mounted
        # on the current directory (typically "/dev").
        # Later, this will be used to suppress creation of device nodes
        # that are supplied by the fdesc file system.
        #
        fdesc_mounted=false
        if [ -d fd ]; then
                # Parse the output from "mount -u -o nosuchoption .".
                # We don't parse the output from df(1) because that's
                # less likely to be available on install media.
                #
                # If the current directory is a mount point for the
                # fdesc file system, then the expected output (whether
                # or not the current user is root) is:
                #       mount_fdesc: -o suchoption: option not supported.
                #
                # If the current directory is not a mount point, then
                # the expected output is:
                #       mount: .: unknown special file or file system.
                #
                # If we are not running on NetBSD, or mount(8) is not
                # found, then we should get some other error message.
                #
                case "$({ LC_ALL=C mount -u -o nosuchoption . ; } 2>&1)" in
                *mount_fdesc*)  fdesc_mounted=true ;;
                esac
        fi

        # do_force requires mknod
        if $do_force; then
                if $do_mtree || $do_pax || $do_specfile; then
                        die "-f option works only with mknod"
                fi
                do_mknod=true
        fi

        # do_force and do_update do not work together
        if $do_force && $do_update; then
                die "-f and -u options do not work together"
        fi

        # If no explicit method was specified on the command line or
        # forced above, then use one of mtree, pax, or mknod, in that
        # order of preference.
        #
        # mtree is preferred because it's fast and designed for the
        # purpose.  However, it's unlikely to be available early in the
        # boot sequence, when init(8) may invoke MAKEDEV(8).
        #
        # pax is usually acceptable, and it's likely to be available
        # early in the boot sequence.  However, it's much slower than mtree.
        #
        # mknod is just very slow, because the shell has to fork for
        # each device node.
        #
        if ! ( $do_mtree || $do_pax || $do_mknod || $do_specfile ); then
                if check_mtree "${TOOL_MTREE}"; then
                        do_mtree=true
                elif check_pax "${TOOL_PAX}"; then
                        do_pax=true
                else
                        do_mknod=true
                fi
        fi

        # Now we need exactly one node-creation method.
        case $(( $($do_mtree && echo 1 || echo 0) + \
                $($do_pax && echo 1 || echo 0) + \
                $($do_mknod && echo 1 || echo 0) + \
                $($do_specfile && echo 1 || echo 0) ))
        in
        1)      : OK ;;
        *)      die "-m, -p, -s, and -t options are mutually exclusive" ;;
        esac

        # If we are using mknod, then decide what options to pass it.
        if $do_mknod; then
                MKNOD="${TOOL_MKNOD:-mknod} -F netbsd"
                if $do_force; then
                        MKNOD="${MKNOD} -R"
                else
                        MKNOD="${MKNOD} -r"
                fi
        fi

        # do_mtree or do_pax internally implies do_specfile.
        # This happens after checking for mutually-exclusive options.
        if ($do_mtree || $do_pax) && ! $do_specfile; then
                do_specfile=true
                opts="${opts} -s"
        fi
}

# specfile_before
#       This is called before the bulk of the makedev processing,
#       if do_specfile is set.
#
#       It simply prints ". type=dir optional", which must be the
#       first line of the specfile.
#
specfile_before()
{
        echo ". type=dir optional"
}

# mtree_after
#       Output in specfile format is piped into this function.
#
#       It uses mtree to create the devices defined in the specfile.
#
mtree_after()
{
        nooutput -1 "${TOOL_MTREE}" -e -U
}

# pax_after
#       Output in specfile format is piped into this function.
#
#       It uses pax to create the devices defined in the specfile.
#
pax_after()
{
        # Run pax in an empty directory, so it pays
        # attention only to the specfile, without being
        # confused by the existing contents of the target
        # directory.  Without this, pax would complain "file
        # would overwrite itself" for already-existing
        # device nodes.
        tmpdir=./tmp.$$
        mkdir "${tmpdir}" || die "can't create temporary directory"
        cd "${tmpdir}" || die "can't cd to temporary directory"
        "${TOOL_PAX}" -r -w -M -pe ..
        pax_status=$?
        cd .. # back to where we started
        rmdir "${tmpdir}"
        return $pax_status
}

# makedev_main makedev_name args...
#       Perform most of the work of the main program.  makedev_name
#       is typically "makedev", but may be the name of some other
#       makedev-like function (if we are invoked from MAKEDEV.local or
#       some other script).  The other args to this function are the
#       command line args with which the MAKEDEV (or MAKEDEV.local)
#       script was invoked.
#
makedev_main()
{
        local makedev="$1" ; shift

        # Parse command line args
        setup ${1+"$@"}
        shift $((${OPTIND}-1))

        if $do_create_mfs; then
                # Count inodes and create mfs file system.
                # The makedev call merely updates $count_nodes.
                count_nodes=0
                $makedev ${1+"$@"}
                create_mfs_dev $count_nodes
                unset count_nodes
        fi

        # Set before, middle, and after variables, so we can do
        # something like "( $before && $middle ) | $after",
        # except it will have to be more complex so we can capture
        # the exit status from both sides of the pipe.
        #
        if $do_specfile; then
                before=specfile_before
        else
                before=:
        fi
        middle='$makedev ${1+"$@"} && (exit $status)'
        if $do_mtree; then
                after=mtree_after
        elif $do_pax ; then
                after=pax_after
        else
                after=cat
        fi

        # Actually perform the "{ $before && $middle } | $after" commands.
        #
        # We go to some trouble to ensure that, if any of
        # $before, $middle, or $after fails, then we also
        # exit with a non-zero status.
        #
        # In the block below, fd 3 is a copy of the original stdout,
        # and fd 4 goes to a subshell that analyses the exit status
        # status from the other commands.
        #
        {
                exec 3>&1;
                {
                        { eval "$before" && eval "$middle"; echo $? >&4; } \
                        | { eval "$after"; echo $? >&4; } \
                } 4>&1 1>&3 \
                | (
                        read status1;
                        read status2;
                        case "$status1,$status2" in
                        0,0) exit 0;;
                        0,*) exit $status2;;
                        *,*) exit $status1;;
                        esac
                )
        }
}

#
# functions available to create nodes:
#
# mkdev name [b|c] major minor [mode{=600} [gid{=0} [uid{=0}]]]
#       create device node `name' with the appropriate permissions
#
# lndev src target
#       create a symlink from src to target
#
# makedir dir mode
#       create directory with appropriate mode
#

mkdev()
{
        if [ -n "$count_nodes" ]; then
                count_nodes=$((count_nodes + 1))
                return
        fi
        if $do_update && test -e $1; then
                return
        fi
        if $do_specfile; then
                case $2 in
                b)      type=block ;;
                c)      type=char ;;
                esac
                echo "./$1 type=${type} device=netbsd,$3,$4 mode=${5:-600} gid=${6:-$g_wheel} uid=${7:-$u_root}"
        else
                ${MKNOD} -m ${5:-600} -g \#${6:-$g_wheel} -u \#${7:-$u_root} $1 $2 $3 $4
        fi
}

lndev()
{
        if [ -n "$count_nodes" ]; then
                count_nodes=$((count_nodes + 1))
                return
        fi
        if $do_update && test -e $2; then
                return
        fi
        if $do_specfile; then
                echo "./$2 type=link link=$1 mode=0700 gid=$g_wheel uid=$u_root"
        else
                ln -f -s $1 $2
        fi
}

makedir()
{
        if [ -n "$count_nodes" ]; then
                count_nodes=$((count_nodes + 1))
                return
        fi
        if $do_update && test -e $1; then
                return
        fi
        if $do_specfile; then
                echo "./$1 type=dir mode=$2 gid=$g_wheel uid=$u_root"
        else
                nooutput -2 mkdir $1
                chmod $2 $1
        fi
}

warn()
{
        echo 1>&2 "$0: $*"
        status=1
}

die()
{
        echo 1>&2 "$0: $*"
        exit 1
}

# makedev special [...]
#       the main loop
#
makedev()
{

for i
do

case $i in

all_md)
        makedev mt0 mt1 ts0 ts1 st0 st1 uk0 ss0 cd0 vt0
        makedev ra0 ra1 ra2 ra3 hp0 hp1 hp2 hp3 sd0 sd1 sd2 sd3 rd0 rd1 rd2
        makedev dz0 dl0 dhu0 rx0 rx1 racd0 racd1
        makedev scsibus0 scsibus1 scsibus2 scsibus3
        makedev ses0 ses1 ses2 ses3
        makedev std_vax
        ;;

std_vax)
        mkdev ttyg0             c 25 0
        mkdev ttyg1             c 25 1
        mkdev ttyg2             c 25 2
        mkdev ttyg3             c 25 3
        mkdev floppy            c 8 0
        mkdev crl               c 35 0
        mkdev csa1              c 51 0
        mkdev csa2              c 51 1
        mkdev tu0               b 8 0
        mkdev tu1               b 8 1
        mkdev kUmem             c 3 3
        mkdev leds              c 3 13  666
        ;;

ht[0-9]*|tm[0-9]*|mt[0-9]*|ts[0-9]*|ut[0-9]*)
        case $i in
        ht*) name=ht;   unit=${i#ht};   blk=1; chr=5 ;;
        mt*) name=mt;   unit=${i#mt};   blk=15; chr=38;;
        tm*) name=tm;   unit=${i#tm};   blk=5; chr=14;;
        ts*) name=ts;   unit=${i#ts};   blk=6; chr=16;;
        ut*) name=ut;   unit=${i#ut};   blk=10; chr=17;;
        esac
        case $unit in
        [0-7])
                four=$(($unit + 4)) ; eight=$(($unit + 8))
                twelve=$(($unit + 12)) ; twenty=$(($unit + 20))
                mkdev $name$unit        b $blk $unit    660 $g_operator
                mkdev $name$four        b $blk $four    660 $g_operator
                mkdev $name$eight       b $blk $eight   660 $g_operator
                mkdev $name$twelve      b $blk $twelve  660 $g_operator
                        # next 4 are for sanity with pdp11 v7
                mkdev n$name$unit       b $blk $four    660 $g_operator
                mkdev n$name$eight      b $blk $twelve  660 $g_operator
                mkdev nr$name$unit      c $chr $four    660 $g_operator
                mkdev nr$name$eight     c $chr $twelve  660 $g_operator
                mkdev r$name$unit       c $chr $unit    660 $g_operator
                mkdev r$name$four       c $chr $four    660 $g_operator
                mkdev r$name$eight      c $chr $eight   660 $g_operator
                mkdev r$name$twelve     c $chr $twelve  660 $g_operator
                if [ $i = ut ]; then
                        mkdev $name$twenty      b $blk $twenty  660 $g_operator
                        mkdev r$name$twenty     c $chr $twenty  660 $g_operator
                fi
                ;;
        *)
                warn "bad unit for tape in: $1"
                ;;
        esac
        ;;

hp[0-9]*|hk[0-9]*|up[0-9]*|ra[0-9]*|rl[0-9]*|rb[0-9]*|rd[0-9]*|racd[0-1]*|rx[0-9]*)
        case $i in
        hp*) name=hp;   unit=${i#hp};   blk=0; chr=4;;
        hk*) name=hk;   unit=${i#hk};   blk=3; chr=11;;
        up*) name=up;   unit=${i#up};   blk=2; chr=13;;
        rb*) name=rb;   unit=${i#rb};   blk=11; chr=23;;
        racd*) name=racd;       unit=${i#racd}; blk=28; chr=28;;
        ra*) name=ra;   unit=${i#ra};   blk=9;  chr=9;;
        rx*) name=rx;   unit=${i#rx};   blk=12; chr=30;;
        rl*) name=rl;   unit=${i#rl};   blk=14; chr=32;;
        rd*) name=rd;   unit=${i#rd};   blk=19; chr=58;;
        esac
        makedisk_p8 $name $unit $blk $chr
        ;;

uu[0-9]*)
        unit=${i#uu}
        name=uu; blk=13
        case $unit in
        [0-3])
                mkdev ${name}${unit}    b $blk $(($unit * 2 + 0))
                mkdev ${name}${unit}a   b $blk $(($unit * 2 + 1))
                ;;
        *)
                warn "bad unit for uu in: $i"
                ;;
        esac
        ;;

dz[0-9]*)
        unit=${i#dz}
        case $unit in
        [0-7])
                i=0
                while [ $i -lt 8 ]
                do
                        oi=$(($unit * 8 + $i))
                        zoi=00$oi
                        zoi=${zoi#${zoi%??}}
                        mkdev tty$zoi c 1 $oi
                        i=$(($i + 1))
                done
                ;;
        *)
                warn "bad unit for dz in: $i"
                ;;
        esac
        ;;

dhu[0-9]*|dh[0-9]*|dmf[0-9]*|dmz[0-9]*|vt[0-9]*)
        case $i in
        vt*)    name=vt; major=68; count=8
                unit=${i#vt}
                case $unit in
                0) ch=w ;;
                *) warn "bad unit for $name in: $i" ;;
                esac
                ;;
        dmz*)   name=dmz; major=37; count=24
                unit=${i#dmz}
                case $unit in
                0) ch=a ;;
                1) ch=b ;;
                2) ch=c ;;
                3) ch=e ;;
                4) ch=f ;;
                *) warn "bad unit for $name in: $i" ;;
                esac
                ;;
        dmf*)   name=dmf; major=22; count=8
                unit=${i#dmf}
                case $unit in
                0) ch=A ;;
                1) ch=B ;;
                2) ch=C ;;
                3) ch=E ;;
                4) ch=F ;;
                5) ch=G ;;
                6) ch=H ;;
                7) ch=I ;;
                *) warn "bad unit for $name in: $i" ;;
                esac
                ;;
        dhu*)   name=dhu; major=34; count=16
                unit=${i#dhu}
                case $unit in
                0) ch=S ;;
                1) ch=T ;;
                2) ch=U ;;
                3) ch=V ;;
                4) ch=W ;;
                5) ch=X ;;
                6) ch=Y ;;
                7) ch=Z ;;
                *) warn "bad unit for $name in: $i" ;;
                esac
                ;;
        dh*)    name=dh; major=12; count=16
                unit=${i#dh}
                case $unit in
                0) ch=h ;;
                1) ch=i ;;
                2) ch=j ;;
                3) ch=k ;;
                4) ch=l ;;
                5) ch=m ;;
                6) ch=n ;;
                7) ch=o ;;
                *) warn "bad unit for $name in: $i" ;;
                esac
                ;;
        esac
        i=0
        while [ $i -lt $count ]
        do
                mkdev tty$ch$(hexprint $i) c $major $(($unit * $count + $i))
                i=$(($i + 1))
        done

        ;;

dl[0-9]*)
        unit=${i#dl}
        mkdev ttyJ$(hexprint $unit) c 66 $unit
        ;;

lp[0-9]*|va[0-9]*|vp[0-9]*)
        case $i in
        lp*) name=lp; unit=${i#lp}; major=15;;
        va*) name=va; unit=${i#va}; major=10;;
        vp*) name=vp; unit=${i#vp}; major=6;;
        esac
        case $unit in
        [0-7])
                mkdev $i c $major $unit 666
                ;;
        *)
                warn "bad unit for $name in: $i"
                ;;
        esac
        ;;

np[0-9]*)
        class=${i#np}
        case $class in
        0) offset=0 name=0;;
        1) offset=16 name=1;;
        2) offset=32 name=2;;
        *) warn "bad unit for np in: $i" ;;
        esac
        case $class in
        0|1|2)
        i=0
        while [ $i -lt 4 ]
        do
                oi=$(($offset + $i))
                zoi=$(zeropad 2 $oi)
                mkdev np$zoi c 39 $oi
                i=$(($i + 1))
        done
        esac
        ;;

dn[0-9]*|ik[0-9]*|ps[0-9]*|ad[0-9]*|ct[0-9]*)
        case $i in
        ct*) name=ct; unit=${i#ct}; chr=18;;
        dn*) name=cu; unit=${i#dn}; chr=24;;
        ps*) name=ps; unit=${i#ps}; chr=27;;
        ad*) name=ad; unit=${i#ad}; chr=29;;
        ik*) name=ik; unit=${i#ik}; chr=31;;
        esac
        case $unit in
        [0-7])
                mkdev ${name}${unit} c ${chr} ${unit} 666
                ;;
        *)
                warn "bad unit for $name in: $i"
                ;;
        esac
        ;;

qd[0-9]*)
        unit=${i#qd}
        mkdev qc$unit c 40 $(($unit * 4))
        mkdev qd$unit c 40 $(($unit * 4 + 2))
        ;;

qv0)
        mkdev qv0 c 40 0
        mkdev qvcons c 40 1
        mkdev mouse c 40 2
        ;;

all)
        makedev all_md
        makedev std fd ptm pty0 pty1 pty2 pty3
        makedev ccd0 ccd1 ccd2 ccd3
        makedev cgd0 cgd1 cgd2 cgd3
        makedev fss0 fss1 fss2 fss3
        makedev md0 md1
        makedev raid0 raid1 raid2 raid3 raid4 raid5 raid6 raid7
        makedev vnd0 vnd1 vnd2 vnd3
        makedev iscsi0
        makedev bpf npf
        makedev tun0 tun1 tun2 tun3
        makedev ipl pf crypto random
        makedev lockstat clockctl cpuctl
        makedev atabus0 atabus1 atabus2 atabus3 atabus4 atabus5 atabus6 atabus7
        makedev tap tap0 tap1 tap2 tap3
        makedev gpio gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
        makedev pad pad0 pad1 pad2 pad3
        makedev bthub
        makedev putter
        makedev drvctl
        makedev video
        makedev dtv
        makedev drm0
        makedev altmem
        makedev zfs
        makedev local # do this last
        ;;

init)
        # unless overridden by MD entry, this is equal to 'all'
        makedev all
        ;;

audio)
        makedev audio0 audio1 audio2 audio3
        makedev hdaudio0 hdaudio1 hdaudio2 hdaudio3
        lndev sound0 sound
        lndev audio0 audio
        lndev mixer0 mixer
        lndev audioctl0 audioctl
        ;;

gpio)
        makedev gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
        lndev gpio0 gpio
        ;;

pad)
        makedev pad0 pad1 pad2 pad3
        lndev pad0 pad
        ;;

radio)
        makedev radio0 radio1
        lndev radio0 radio
        ;;

video)
        makedev video0 video1 video2 video3
        ;;

dtv)
        makedev dtv0 dtv1 dtv2 dtv3
        ;;

iic)
        makedev iic0 iic1 iic2 iic3
        ;;

altmem)
        makedev altmem0 altmem1
        ;;

ramdisk)
        makedev floppy md0
        ;;

usbs)
        makedev usb usb0 usb1 usb2 usb3 usb4 usb5 usb6 usb7
        makedev uhid0 uhid1 uhid2 uhid3
        makedev ulpt0 ulpt1
        makedev ttyU0 ttyU1
        makedev ttyY0 ttyY1
        makedev ttyHS0
        makedev urio0
        makedev uscanner0 uscanner1
        makedev utoppy0 utoppy1
        makedev ugen0 ugen1 ugen2 ugen3
        ;;

isdns)
        makedev isdn isdnctl isdnbchan0 isdnbchan1 isdntel0 isdntel1 isdnteld0 isdnteld1 isdntrc0 isdntrc1
        ;;

std)
        mkdev           console c 0 0   600
        mkdev           constty c 0 1   600
        mkdev           drum    c 7 0   640 $g_kmem
        mkdev           kmem    c 3 1   640 $g_kmem
        mkdev           mem     c 3 0   640 $g_kmem
        mkdev           null    c 3 2   666
        mkdev           zero    c 3 12  666
        mkdev           klog    c 33 0  600
        mkdev           ksyms   c 79 0 444
        if ! $fdesc_mounted; then
                mkdev   tty     c 2 0           666
                mkdev   stdin   c 53 0  666
                mkdev   stdout  c 53 1  666
                mkdev   stderr  c 53 2  666
        fi
        ;;

utoppy[0-9]*)
        unit=${i#utoppy}
        mkdev utoppy$unit c 174 $unit
        ;;

ttyHS[0-9]*)
        unit=${i#ttyHS}
        for j in 00 01 02 03 04 05 06 07 08 09 10
        do
                base=$(($unit * 16 + ${j#0}))
                mkdev ttyHS$unit.$j c 196 $(($base + $dialin  )) "" "" $u_uucp
                mkdev dtyHS$unit.$j c 196 $(($base + $dialout )) "" "" $u_uucp
                mkdev ctyHS$unit.$j c 196 $(($base + $callunit)) "" "" $u_uucp
        done
        ;;

ttyY[0-9]*)
        unit=${i#ttyY}
        mkdev ttyY$unit c 172 $(($unit + $dialin  )) "" "" $u_uucp
        mkdev dtyY$unit c 172 $(($unit + $dialout )) "" "" $u_uucp
        mkdev ctyY$unit c 172 $(($unit + $callunit)) "" "" $u_uucp
        ;;

wscons)
        makedev ttyE0 ttyE1 ttyE2 ttyE3 ttyE4 ttyE5 ttyE6 ttyE7
        makedev wsmouse0 wsmouse1 wsmouse2 wsmouse3
        makedev wskbd0 wskbd1 wskbd2 wskbd3
        makedev wsmux0 wsmux1 wsmux2 wsmux3
        makedev wsmouse wskbd
        makedev ttyEcfg ttyEstat
        makedev wsfont
        ;;

wsmouse)
        mkdev wsmouse c 74 0
        ;;

wskbd)
        mkdev wskbd c 74 1
        ;;

wsmux[0-9]*)
        unit=${i#wsmux}
        mkdev wsmux$unit    c 74 $unit
        mkdev wsmuxctl$unit c 74 $(($unit + 128)) 200
        ;;

ttyEstat)
        mkdev ttyEstat c 68 254
        ;;

ttyEcfg)
        mkdev ttyEcfg c 68 255
        ;;

ttyE[0-9]*)
        unit=${i#ttyE}
        mkdev ttyE$unit c 68 $unit
        ;;

wsmouse[0-9]*)
        unit=${i#wsmouse}
        mkdev wsmouse$unit c 70 $unit
        ;;

wskbd[0-9]*)
        unit=${i#wskbd}
        mkdev wskbd$unit c 69 $unit
        ;;

fd)
        if ! $fdesc_mounted; then
                # Create the "fd" subdirectory, and devices "fd/0" to "fd/63"
                makedir fd 755
                n=0
                while [ $n -lt 64 ]
                do
                        mkdev fd/$n c 53 $n 666
                        n=$(($n + 1))
                done
        fi
        ;;

md[0-9]*)
        makedisk_minimal md ${i#md} 23 62
        ;;

fss[0-9]*)
        name=fss; unit=${i#fss};        blk=163;        chr=163
        mkdev $name$unit        b $blk $unit 660 $g_operator
        mkdev r$name$unit       c $chr $unit 660 $g_operator
        ;;

ss[0-9]*)
        name=ss;        unit=${i#ss};   chr=64
        mkdev $name$unit        c $chr $(($unit * 16 + 0)) 640 $g_operator
        mkdev n$name$unit       c $chr $(($unit * 16 + 1)) 640 $g_operator
        mkdev en$name$unit      c $chr $(($unit * 16 + 3)) 640 $g_operator
        ;;

ccd[0-9]*|cgd[0-9]*|raid[0-9]*|vnd[0-9]*)
        case $i in
        ccd*)   name=ccd;       unit=${i#ccd};  blk=17; chr=54;;
        cgd*)   name=cgd;       unit=${i#cgd};  blk=26; chr=77;;
        raid*)  name=raid;      unit=${i#raid}; blk=25; chr=73;;
        vnd*)   name=vnd;       unit=${i#vnd};  blk=18; chr=55;;
        esac
        makedisk_p8 $name $unit $blk $chr
        ;;

sd[0-9]*)
        name=sd; unit=${i#sd};  blk=20; chr=59
        makedisk_p8 $name $unit $blk $chr
        ;;

flash[0-9]*)
        unit=${i#flash}
        flash=flash$unit
        mkdev flash$unit b 199 $unit
        mkdev rflash$unit c 199 $unit
        ;;

altmem[0-9]*)
        name=altmem; unit=${i#altmem}; blk=182; chr=182
        makedisk_p8 $name $unit $blk $chr
        ;;

bio)
        mkdev bio c 181 0
        ;;

dk[0-9]*)
        name=dk; unit=${i#dk}; blk=168; chr=168
        mkdev r$name$unit c $chr $unit 0640 $g_operator
        mkdev $name$unit b $blk  $unit 0640 $g_operator
        ;;

opty)
        # Create 16 device nodes, [pt]typ0 to [pt]typf,
        # same as "MAKEDEV pty0".
        for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f
        do
                case $j in
                [0-9])  jn=$j ;;
                a)      jn=10 ;;
                b)      jn=11 ;;
                c)      jn=12 ;;
                d)      jn=13 ;;
                e)      jn=14 ;;
                f)      jn=15 ;;
                esac
                mkdev ttyp$j c 20 $jn 666
                mkdev ptyp$j c 21 $jn 666
        done
        ;;

pty[0-9]*)
        # Each unit number creates up to 16 pairs of {tty,pty} device nodes:
        # pty0 => 16 pairs, [tp]typ0 to [tp]typf
        # pty1 => 16 pairs, [tp]tyq0 to [tp]tyqf
        # pty16 => 16 pairs, [tp]typg to [tp]typv
        # pty17 => 16 pairs, [tp]typw to [tp]typL
        # pty18 => 14 pairs, [tp]typM to [tp]typZ
        class=${i#pty}
        d1="p q r s t u v w x y z P Q R S T"
        if [ "$class" -ge 64 ]
        then
                warn "$i: pty unit must be between 0 and 63"
                continue
        elif [ "$class" -lt 16 ]
        then
                # pty[p-zP-T][0-9a-f]
                offset=0
                mult=0
                d2="0 1 2 3 4 5 6 7 8 9 a b c d e f"
        else
                # pty[p-zP-T][g-zA-Z]
                class=$(($class - 16))
                offset=256
                mult=2
                d2="g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
        fi
        start=$(($class * 16))
        set -- $d2
        nt=$#
        s1=$(($start / $nt))
        set -- $d1
        shift $s1
        t1=$1
        if [ "$t1" = v ]; then
                warn "$i: pty unit conflicts with console ttyv0 device"
                continue
        fi
        s2=$(($start % ($nt - $s1 * $mult)))
        set -- $d2
        shift $s2
        t2=$1
        unit=$(($start + $offset - $s1 * $mult))
        end=$(($unit + 16))
        while [ "$unit" -lt "$end" ]
        do
                mkdev tty$t1$t2 c 20 $unit 666
                mkdev pty$t1$t2 c 21 $unit 666
                shift
                t2=$1
                if [ -z "$t2" ]
                then
                        break
                fi
                unit=$(($unit + 1))
        done
        ;;

st[0-9]*)
        name=st;        unit=${i#st};   chr=60; blk=21
        mkdev $name$unit        b $blk $(($unit * 16 + 0)) 660 $g_operator
        mkdev n$name$unit       b $blk $(($unit * 16 + 1)) 660 $g_operator
        mkdev e$name$unit       b $blk $(($unit * 16 + 2)) 660 $g_operator
        mkdev en$name$unit      b $blk $(($unit * 16 + 3)) 660 $g_operator
        mkdev r$name$unit       c $chr $(($unit * 16 + 0)) 660 $g_operator
        mkdev nr$name$unit      c $chr $(($unit * 16 + 1)) 660 $g_operator
        mkdev er$name$unit      c $chr $(($unit * 16 + 2)) 660 $g_operator
        mkdev enr$name$unit     c $chr $(($unit * 16 + 3)) 660 $g_operator
        ;;

ses[0-9]*|ch[0-9]*|uk[0-9]*)
        case $i in
        ch*)    name=ch;        unit=${i#ch};   chr=63;;
        uk*)    name=uk;        unit=${i#uk};   chr=65;;
        ses*)   name=ses;       unit=${i#ses};  chr=81;;
        esac
        mkdev $name$unit c $chr $unit 640 $g_operator
        ;;

cd[0-9]*)
        makedisk_minimal cd ${i#cd} 22 61
        ;;

bpf)
        mkdev bpf       c 56 0
        lndev bpf bpf0
        ;;

npf)
        mkdev npf       c 198 0
        ;;

bthub)
        mkdev bthub c 175 0
        ;;

tun[0-9]*)
        unit=${i#tun}
        mkdev tun$unit c 57 $unit
        ;;

ipl)
        mkdev ipl       c 42 0
        mkdev ipnat     c 42 1
        mkdev ipstate   c 42 2
        mkdev ipauth    c 42 3
        mkdev ipsync    c 42 4
        mkdev ipscan    c 42 5
        mkdev iplookup  c 42 6
        ;;

pf)
        mkdev pf c 161 0
        ;;

crypto)
        mkdev crypto c 160 0 666
        ;;

lockstat)
        mkdev lockstat c 177 0
        ;;

cpuctl)
        mkdev cpuctl c 188 0 666
        ;;

hdaudio[0-9]*)
        unit=${i#hdaudio}
        mkdev hdaudio$unit c 195 $unit 644
        ;;

gpio[0-9]*)
        unit=${i#gpio}
        mkdev gpio$unit c 173 $unit 644
        ;;

video|video[0-9]*)
        unit=${i#video}
        : ${unit:-0}
        mkdev video$unit c 193 $unit 666
        ;;

dtv[0-9]*)
        unit=${i#dtv}
        makedir dvb 755
        makedir dvb/adapter$unit 755
        mkdev dvb/adapter$unit/frontend0 c 200 $(($unit + 0)) 666
        mkdev dvb/adapter$unit/demux0 c 200 $(($unit + 16)) 666
        mkdev dvb/adapter$unit/dvr0 c 200 $(($unit + 32)) 666
        ;;

iic[0-9]*)
        unit=${i#iic}
        : ${unit:-0}
        mkdev iic$unit c 201 $unit 600
        ;;

amr[0-9]*)
        unit=${i#amr}
        mkdev amr$unit c 176 $unit
        ;;

random)
        mkdev random    c 67 0 444
        mkdev urandom   c 67 1 644
        ;;

cfs)
        makedev cfs0
        ;;

scsibus[0-9]*)
        unit=${i#scsibus}
        mkdev scsibus$unit c 72 $unit 644
        ;;

bktr)
        makedev bktr0 bktr1
        lndev   bktr0   bktr
        lndev   tuner0  tuner
        lndev   vbi0    vbi
        ;;

io)
        mkdev           io      c 3 14  600
        ;;

twa[0-9]*)
        unit=${i#twa}
        mkdev twa$unit c 187 $unit
        ;;

vmegen)
        makedev vmegen0 vmegen1 vmegen2 vmegen3
        ;;

wsfont)
        mkdev wsfont c 80 0
        ;;

pad[0-9]*)
        unit=${i#pad}
        mkdev pad$unit c 189 $unit 444
        ;;

clockctl)
        mkdev clockctl c 75 0 660 $g_ntpd
        ;;

nsmb)
        makedev nsmb0 nsmb1 nsmb2 nsmb3
        ;;

nsmb[0-9]*)
        unit=${i#nsmb}
        mkdev nsmb$unit c 98 $unit 644
        ;;

veriexec)
        mkdev veriexec c 170 0 600
        ;;

mouse-pms[0-9]*|mouse-qms[0-9]*)
        case $i in
        mouse-pms*) name=pms ;;
        mouse-qms*) name=qms ;;
        esac
        unit=${i#mouse-${name}}
        lndev $name$unit mouse
        ;;

ipty)
        mkdev ttyp0 c 20 0 666
        mkdev ttyp1 c 20 1 666
        mkdev ptyp0 c 21 0 666
        mkdev ptyp1 c 21 1 666
        ;;

ptm)
        makedir pts 755
        mkdev ptmx c 165 0 666
        mkdev ptm c 165 1 666
        ;;

atabus[0-9]*)
        unit=${i#atabus}
        mkdev atabus$unit c 166 $unit 644
        ;;

drm[0-9]*)
        unit=${i#drm}
        makedir dri 755
        mkdev dri/card$unit c 180 $unit 660
        ;;

drvctl)
        mkdev drvctl c 167 0 644
        ;;

isv)
        mkdev isv c 192 0 644
        ;;

tap|tap[0-9]*)
        unit=${i#tap}
        case "$unit" in
        [0-9]*)
                mkdev tap${unit} c 169 ${unit} 600
                ;;
        "")
                mkdev tap c 169 0xfffff 600
                ;;
        esac
        ;;

tpm)
        mkdev tpm c 204 0 600
        ;;

fw[0-9]*)
        unit=${i#fw}
        for j in 0 1 2 3
        do
                mkdev fw${unit}.${j} c 171 $((${unit} * 256 + ${j})) 660 ${g_operator}
                mkdev fwmem${unit}.${j} c 171 $((65536 + ${unit} * 256 + ${j})) 660 ${g_operator}
        done
        ;;

# create putter device and symlinks for all subsystems using it
putter)
        mkdev putter c 178 0 600
        mkdev pud c 178 1 600
        lndev putter puffs
        ;;

zfs)
        mkdev zfs c 190 0 600
        makedir zpool 755
        ;;

iscsi[0-9]*)
        unit=${i#iscsi}
        mkdev iscsi${unit} c 203 0 600
        ;;

local)
        if [ -f "$0.local" ]; then
                umask 0
                if [ -n "$count_nodes" ]; then
                        count_nodes=$((count_nodes + \
                            $(linecount "$(sh "$0.local" $opts -s all)") ))
                else
                        sh "$0.local" $opts all
                fi
                umask 077
        fi
        ;;

*)
        warn "$i: unknown device"
        ;;

esac
done

}


# three variants of disk partitions - max 8, max 16, max 16 with highpartoffset
# hack; only the one used by port is retained in final MAKEDEV script
# routine is called as:
# makedisk name unit blk chr
makedisk_p8()
{
        name="$1"; unit="$2"; blk="$3"; chr="$4"

        mkdev ${name}${unit}a   b $blk $(($unit * 8 + 0))       640 $g_operator
        mkdev ${name}${unit}b   b $blk $(($unit * 8 + 1))       640 $g_operator
        mkdev ${name}${unit}c   b $blk $(($unit * 8 + 2))       640 $g_operator
        mkdev ${name}${unit}d   b $blk $(($unit * 8 + 3))       640 $g_operator
        mkdev ${name}${unit}e   b $blk $(($unit * 8 + 4))       640 $g_operator
        mkdev ${name}${unit}f   b $blk $(($unit * 8 + 5))       640 $g_operator
        mkdev ${name}${unit}g   b $blk $(($unit * 8 + 6))       640 $g_operator
        mkdev ${name}${unit}h   b $blk $(($unit * 8 + 7))       640 $g_operator
        mkdev r${name}${unit}a  c $chr $(($unit * 8 + 0))       640 $g_operator
        mkdev r${name}${unit}b  c $chr $(($unit * 8 + 1))       640 $g_operator
        mkdev r${name}${unit}c  c $chr $(($unit * 8 + 2))       640 $g_operator
        mkdev r${name}${unit}d  c $chr $(($unit * 8 + 3))       640 $g_operator
        mkdev r${name}${unit}e  c $chr $(($unit * 8 + 4))       640 $g_operator
        mkdev r${name}${unit}f  c $chr $(($unit * 8 + 5))       640 $g_operator
        mkdev r${name}${unit}g  c $chr $(($unit * 8 + 6))       640 $g_operator
        mkdev r${name}${unit}h  c $chr $(($unit * 8 + 7))       640 $g_operator
}

makedisk_p16()
{
        name="$1"; unit="$2"; blk="$3"; chr="$4"

        mkdev ${name}${unit}a   b $blk $(($unit * 16 + 0))      640 $g_operator
        mkdev ${name}${unit}b   b $blk $(($unit * 16 + 1))      640 $g_operator
        mkdev ${name}${unit}c   b $blk $(($unit * 16 + 2))      640 $g_operator
        mkdev ${name}${unit}d   b $blk $(($unit * 16 + 3))      640 $g_operator
        mkdev ${name}${unit}e   b $blk $(($unit * 16 + 4))      640 $g_operator
        mkdev ${name}${unit}f   b $blk $(($unit * 16 + 5))      640 $g_operator
        mkdev ${name}${unit}g   b $blk $(($unit * 16 + 6))      640 $g_operator
        mkdev ${name}${unit}h   b $blk $(($unit * 16 + 7))      640 $g_operator
        mkdev ${name}${unit}i   b $blk $(($unit * 16 + 8))      640 $g_operator
        mkdev ${name}${unit}j   b $blk $(($unit * 16 + 9))      640 $g_operator
        mkdev ${name}${unit}k   b $blk $(($unit * 16 + 10))     640 $g_operator
        mkdev ${name}${unit}l   b $blk $(($unit * 16 + 11))     640 $g_operator
        mkdev ${name}${unit}m   b $blk $(($unit * 16 + 12))     640 $g_operator
        mkdev ${name}${unit}n   b $blk $(($unit * 16 + 13))     640 $g_operator
        mkdev ${name}${unit}o   b $blk $(($unit * 16 + 14))     640 $g_operator
        mkdev ${name}${unit}p   b $blk $(($unit * 16 + 15))     640 $g_operator
        mkdev r${name}${unit}a  c $chr $(($unit * 16 + 0))      640 $g_operator
        mkdev r${name}${unit}b  c $chr $(($unit * 16 + 1))      640 $g_operator
        mkdev r${name}${unit}c  c $chr $(($unit * 16 + 2))      640 $g_operator
        mkdev r${name}${unit}d  c $chr $(($unit * 16 + 3))      640 $g_operator
        mkdev r${name}${unit}e  c $chr $(($unit * 16 + 4))      640 $g_operator
        mkdev r${name}${unit}f  c $chr $(($unit * 16 + 5))      640 $g_operator
        mkdev r${name}${unit}g  c $chr $(($unit * 16 + 6))      640 $g_operator
        mkdev r${name}${unit}h  c $chr $(($unit * 16 + 7))      640 $g_operator
        mkdev r${name}${unit}i  c $chr $(($unit * 16 + 8))      640 $g_operator
        mkdev r${name}${unit}j  c $chr $(($unit * 16 + 9))      640 $g_operator
        mkdev r${name}${unit}k  c $chr $(($unit * 16 + 10))     640 $g_operator
        mkdev r${name}${unit}l  c $chr $(($unit * 16 + 11))     640 $g_operator
        mkdev r${name}${unit}m  c $chr $(($unit * 16 + 12))     640 $g_operator
        mkdev r${name}${unit}n  c $chr $(($unit * 16 + 13))     640 $g_operator
        mkdev r${name}${unit}o  c $chr $(($unit * 16 + 14))     640 $g_operator
        mkdev r${name}${unit}p  c $chr $(($unit * 16 + 15))     640 $g_operator
}

makedisk_p16high()
{
        ho=524280       # offset for partition 9 to 16
        name="$1"; unit="$2"; blk="$3"; chr="$4"

        mkdev ${name}${unit}a   b $blk $(($unit * 8 + 0))       640 $g_operator
        mkdev ${name}${unit}b   b $blk $(($unit * 8 + 1))       640 $g_operator
        mkdev ${name}${unit}c   b $blk $(($unit * 8 + 2))       640 $g_operator
        mkdev ${name}${unit}d   b $blk $(($unit * 8 + 3))       640 $g_operator
        mkdev ${name}${unit}e   b $blk $(($unit * 8 + 4))       640 $g_operator
        mkdev ${name}${unit}f   b $blk $(($unit * 8 + 5))       640 $g_operator
        mkdev ${name}${unit}g   b $blk $(($unit * 8 + 6))       640 $g_operator
        mkdev ${name}${unit}h   b $blk $(($unit * 8 + 7))       640 $g_operator
        mkdev ${name}${unit}i   b $blk $(($unit * 8 + $ho + 8)) 640 $g_operator
        mkdev ${name}${unit}j   b $blk $(($unit * 8 + $ho + 9)) 640 $g_operator
        mkdev ${name}${unit}k   b $blk $(($unit * 8 + $ho + 10)) 640 $g_operator
        mkdev ${name}${unit}l   b $blk $(($unit * 8 + $ho + 11)) 640 $g_operator
        mkdev ${name}${unit}m   b $blk $(($unit * 8 + $ho + 12)) 640 $g_operator
        mkdev ${name}${unit}n   b $blk $(($unit * 8 + $ho + 13)) 640 $g_operator
        mkdev ${name}${unit}o   b $blk $(($unit * 8 + $ho + 14)) 640 $g_operator
        mkdev ${name}${unit}p   b $blk $(($unit * 8 + $ho + 15)) 640 $g_operator
        mkdev r${name}${unit}a  c $chr $(($unit * 8 + 0))       640 $g_operator
        mkdev r${name}${unit}b  c $chr $(($unit * 8 + 1))       640 $g_operator
        mkdev r${name}${unit}c  c $chr $(($unit * 8 + 2))       640 $g_operator
        mkdev r${name}${unit}d  c $chr $(($unit * 8 + 3))       640 $g_operator
        mkdev r${name}${unit}e  c $chr $(($unit * 8 + 4))       640 $g_operator
        mkdev r${name}${unit}f  c $chr $(($unit * 8 + 5))       640 $g_operator
        mkdev r${name}${unit}g  c $chr $(($unit * 8 + 6))       640 $g_operator
        mkdev r${name}${unit}h  c $chr $(($unit * 8 + 7))       640 $g_operator
        mkdev r${name}${unit}i  c $chr $(($unit * 8 + $ho + 8)) 640 $g_operator
        mkdev r${name}${unit}j  c $chr $(($unit * 8 + $ho + 9)) 640 $g_operator
        mkdev r${name}${unit}k  c $chr $(($unit * 8 + $ho + 10)) 640 $g_operator
        mkdev r${name}${unit}l  c $chr $(($unit * 8 + $ho + 11)) 640 $g_operator
        mkdev r${name}${unit}m  c $chr $(($unit * 8 + $ho + 12)) 640 $g_operator
        mkdev r${name}${unit}n  c $chr $(($unit * 8 + $ho + 13)) 640 $g_operator
        mkdev r${name}${unit}o  c $chr $(($unit * 8 + $ho + 14)) 640 $g_operator
        mkdev r${name}${unit}p  c $chr $(($unit * 8 + $ho + 15)) 640 $g_operator
}

# make only the very few basic disk device nodes - 'a' partition
# and raw partition
makedisk_minimal()
{
        name=$1; unit=$2; blk=$3; chr=$4
        doff=8
        ro=2
        rn=c

        mkdev ${name}${unit}a   b $blk $(($unit * $doff + 0))   640 $g_operator
        mkdev ${name}${unit}$rn b $blk $(($unit * $doff + $ro)) 640 $g_operator
        mkdev r${name}${unit}a  c $chr $(($unit * $doff + 0))   640 $g_operator
        mkdev r${name}${unit}$rn c $chr $(($unit * $doff + $ro)) 640 $g_operator
}

# create_mfs_dev nodes
#       Create a memory file system for a given number of device nodes,
#       and mount it.  Attempts to use mount_tmpfs, or falls back to
#       mount_mfs.
#
#       If do_redirect, then also redirect output to the console.
#
create_mfs_dev()
{
        ndevnodes=${1-1200}
        dev_mountpoint=${PWD:-/dev}

        # Number of inodes is the specified number of device nodes, plus
        # a margin to allow for extra device nodes created later.
        ninode=$((ndevnodes * 11 / 10))
        # Add 2 reserved inodes (needed for both mfs and tmpfs), and round
        # up to a multiple of 32 (needed for mfs, not needed for tmpfs).
        ninode=$(( (ninode + 2 + 31) / 32 * 32 ))
        # Try tmpfs; if that fails try mfs.
        #
        # For tmpfs, allocate 16KB and 512 byte per node.
        # Actual requirements are much lower, but the size limit
        # is only intended to avoid accidental writing to /dev.
        fs_bytes=$((16384 + ninode * 512))
        if mount_tmpfs -s $fs_bytes -n $ninode -m 0755 \
                -o union tmpfs "$dev_mountpoint"
        then
                fstype=tmpfs
        else
                # This file system size calculation is exact for mount_mfs(8)
                # with 512-byte sectors.  40960 bytes (80 blocks) is the
                # minimum size allowed by mount_mfs.
                fs_bytes=$((8192 + 2 * 8192 + 4096 + ninode*512 + 8192))
                [ "$fs_bytes" -lt 40960 ] && fs_bytes=40960
                fs_blocks=$((fs_bytes/512))
                if mount_mfs -b 4096 -f 512 -s $fs_blocks -n $ninode -p 0755 \
                    -o union swap "$dev_mountpoint"
                then
                        fstype=mfs
                else
                        die "Failed to create memory file system"
                fi
        fi

        # Our current directory was in the lower file system; change it to
        # the newly mounted upper file system.
        cd "$dev_mountpoint"

        if $do_redirect; then
                # Redirect stdout and stderr to console
                mknod -m 600 -g 0 -u 0 temp_console c 0 0
                exec >temp_console 2>&1
                rm temp_console
        fi

        echo "Created $fstype $dev_mountpoint" \
                "($fs_bytes byte, $ninode inodes)"
}

#
# MAIN: If MAKEDEV_AS_LIBRARY is set, then we are being used as a
# function library, so just return.  Otherwise, do all the real work.
#
[ -n "${MAKEDEV_AS_LIBRARY}" ] && return