xref: /netbsd/etc/MAKEDEV.tmpl (revision 64d0289e)
1#!/bin/sh -
2#	$NetBSD: MAKEDEV.tmpl,v 1.233 2022/12/28 19:23:02 jakllsch Exp $
3#
4# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26# POSSIBILITY OF SUCH DAMAGE.
27#
28#
29###########################################################################
30#
31#   PLEASE RUN "cd ../share/man/man8 ; make makedevs"
32#   AFTER CHANGING THIS FILE, AND COMMIT THE UPDATED MANPAGE!
33#
34###########################################################################
35#
36# Device "make" file.  Valid special arguments:
37#	all	makes all known devices, including local devices.
38#		Tries to make the 'standard' number of each type.
39#	init	A set of devices that is used for MFS /dev by init.
40#		May be equal to "all".
41#	floppy	devices to be put on install floppies
42#	ramdisk	devices to be put into INSTALL kernel ramdisks.
43#	std	standard devices
44#	local	configuration specific devices
45#	lua	Lua device
46#	wscons	make wscons devices
47#	usbs	make USB devices
48#
49# Tapes:
50#	st*	SCSI tapes
51#	wt*	QIC-interfaced (e.g. not SCSI) 3M cartridge tape
52#	ht*	MASSBUS TM03 and TU??
53#	mt*	MSCP tapes (e.g. TU81, TK50)
54#	tm*	UNIBUS TM11 and TE10 emulations (e.g. Emulex TC-11)
55#	ts*	UNIBUS TS11
56#	ut*	UNIBUS TU45 emulations (e.g. si 9700)
57#	uu*	TU58 cassettes on DL11 controller
58#
59# Disks:
60#	dk*	wedge disk slices
61#	ccd*	concatenated disk devices
62#	cd*	SCSI or ATAPI CD-ROM
63#	cgd*	cryptographic disk devices
64#	raid*	RAIDframe disk devices
65#	sd*	SCSI disks
66#	wd*	"winchester" disk drives (ST506,IDE,ESDI,RLL,...)
67#	bmd*	Nereid bank memory disks
68#	ed*	IBM PS/2 ESDI disk devices
69#	fd*	"floppy" disk drives (3 1/2", 5 1/4")
70#	fss*	Files system snapshot devices
71#	gdrom*	Dreamcast "gigadisc" CD-ROM drive
72#	hk*	UNIBUS RK06 and RK07
73#	hp*	MASSBUS RM??
74#	ld*	Logical disk devices (e.g., hardware RAID)
75#	mcd*	Mitsumi CD-ROM
76#	md*	memory pseudo-disk devices
77#	ofdisk*	OpenFirmware disk devices
78#	ra*	MSCP disks (RA??, RD??)
79#	rb*	730 IDC w/ RB80 and/or RB02
80#	rd*	HDC9224 RD disks on VS2000
81#	rl*	UNIBUS RL02
82#	rx*	MSCP floppy disk (RX33/50/...)
83#	up*	other UNIBUS devices (e.g. on Emulex SC-21V controller)
84#	vnd*	"file" pseudo-disks
85#	xbd*	Xen virtual disks
86#	xd*	Xylogic 753/7053 disks
87#	xy*	Xylogic 450/451 disks
88#
89# Pointing devices:
90#	wsmouse* wscons mouse events
91#	lms*	Logitech bus mouse
92#	mms*	Microsoft bus mouse
93#	qms*	"quadrature mouse"
94#	pms*	PS/2 mouse
95#	mouse	mouse (provides events, for X11)
96#
97# Keyboard devices:
98#	wskbd*	wscons keyboard events
99#	kbd	raw keyboard (provides events, for X11)
100#	kbdctl	keyboard control
101#
102# Terminals/Console ports:
103#	tty[01]*	standard serial ports
104#	tty0*	SB1250 ("sbscn") serial ports (sbmips)
105#	ttyE*	wscons - Workstation console ("wscons") glass-tty emulators
106#	ttyCZ?	Cyclades-Z multiport serial boards.  Each "unit"
107#		makes 64 ports.
108#	ttyCY?	Cyclom-Y multiport serial boards. Each "unit" makes
109#		32 ports.
110#	ttye*	ITE bitmapped consoles
111#	ttyv0	pccons
112#	ttyC?	NS16550 ("com") serial ports
113#	ttyS*	SA1110 serial port (hpcarm)
114#	ttyTX?	TX39 internal serial ports (hpcmips)
115#	ttyB?	DEC 3000 ZS8530 ("scc") serial ports (alpha)
116#	ttyA*	mfc serial ports (amiga)
117#	ttyB*	msc serial ports (amiga)
118#	ttyC*	com style serial ports (DraCo, HyperCom) (amiga)
119#		On the DraCo, units 0 and 1 are the built-in "modem" and
120#		"mouse" ports, if configured.
121#	ttyA0   8530 Channel A (formerly ser02) (atari)
122#	ttyA1	8530 Channel B (formerly mdm02) (atari)
123#	ttyB0	UART on first 68901 (formerly mdm01) (atari)
124#	ixpcom	IXP12x0 COM ports
125#	epcom	EP93xx COM ports
126#	plcom	ARM PL01[01] serial ports
127#	wmcom	EPOC Windermere COM ports
128#	ttyM?	HP200/300 4 port serial mux interface (hp300)
129#	ttya	"ttya" system console (luna68k)
130#	ttyb	second system serial port (luna68k)
131#	tty*	Onboard serial ports (mvme68k)
132#		On the mvme147 these are: ttyZ1, ttyZ2 and ttyZ3.
133#		On the mvme167, and '177: ttyC1, ttyC2 and ttyC3.
134#		Note that tty[CZ]0 is grabbed by the console device
135#		so is not created by default
136#	dc*	PMAX 4 channel serial interface (kbd, mouse, modem, printer)
137#	scc*	82530 serial interface (pmax)
138#	ttyZ*	Zilog 8530 ("zstty") serial ports
139#	tty[abcd]	Built-in serial ports (sparc)
140#	tty*	Z88530 serial controllers (sparc64)
141#	ttyh*	SAB82532 serial controllers (sparc64)
142#	tty[a-j]	Built-in serial ports (sun2, sun3)
143#	ttyC?	pccons (arc)
144#	dz*	UNIBUS DZ11 and DZ32 (vax)
145#	dh*	UNIBUS DH11 and emulations (e.g. Able DMAX, Emulex CS-11) (vax)
146#	dmf*	UNIBUS DMF32 (vax)
147#	dhu*    UNIBUS DHU11 (vax)
148#	dmz*    UNIBUS DMZ32 (vax)
149#	dl*	UNIBUS DL11 (vax)
150#	xencons	Xen virtual console
151#	ttyVI??	viocon(4)
152#
153# Terminal multiplexors:
154#	dc*	4 channel serial interface (keyboard, mouse, modem, printer)
155#	dh*	UNIBUS DH11 and emulations (e.g. Able DMAX, Emulex CS-11)
156#	dhu*	UNIBUS DHU11
157#	dl*	UNIBUS DL11
158#	dmf*	UNIBUS DMF32
159#	dmz*	UNIBUS DMZ32
160#	dz*	UNIBUS DZ11 and DZ32
161#	scc*	82530 serial interface
162#
163# Call units:
164#	dn*	UNIBUS DN11 and emulations (e.g. Able Quadracall)
165#
166# Pseudo terminals:
167#	ptm	pty multiplexor device, and pts directory
168#	pty*	set of 16 master and slave pseudo terminals
169#	opty	first 16 ptys, to save inodes on install media
170#	ipty	first 2 ptys, for install media use only
171#
172# Printers:
173#	arcpp*	Archimedes parallel port
174#	lpt*	stock lp
175#	lpa*	interruptless lp
176#	par*	Amiga motherboard parallel port
177#	cpi*	Macintosh Nubus CSI parallel printer card
178#
179# USB devices:
180#	usb*	USB control devices
181#	uhid*	USB generic HID devices
182#	ulpt*	USB printer devices
183#	ugen*	USB generic devices
184#	ttyHS*	USB Option N.V. modems
185#	ttyU*	USB modems
186#	ttyY*	USB serial adapters
187#
188# Video devices:
189#	bwtwo*	monochromatic frame buffer
190#	cgtwo*	8-bit color frame buffer
191#	cgthree*	8-bit color frame buffer
192#	cgfour*	8-bit color frame buffer
193#	cgsix*	accelerated 8-bit color frame buffer
194#	cgeight*	24-bit color frame buffer
195#	etvme	Tseng et-compatible cards on VME (atari)
196#	ik*	UNIBUS interface to Ikonas frame buffer
197#	leo	Circad Leonardo VME-bus true color (atari)
198#	ps*	UNIBUS interface to Picture System 2
199#	qv*	QVSS (MicroVAX) display
200#	tcx*	accelerated 8/24-bit color frame buffer
201#
202# Maple bus devices:
203#	maple	Maple bus control devices
204#	mlcd*	Maple bus LCD devices
205#	mmem*	Maple bus storage devices
206#
207# IEEE1394 bus devices:
208#	fw*	IEEE1394 bus generic node access devices
209#	fwmem*	IEEE1394 bus physical memory of the remote node access devices
210#
211# Special purpose devices:
212#	ad*	UNIBUS interface to Data Translation A/D converter
213#	agp*	AGP GART devices
214#	altq	ALTQ control interface
215#	amr*	AMI MegaRaid control device
216#	apm	power management device
217#	audio*	audio devices
218#	bell*	OPM bell device (x68k)
219#	bktr	Brooktree 848/849/878/879 based TV cards
220#	bpf	packet filter
221#	bthub	Bluetooth Device Hub control interface
222#	cfs*	Coda file system device
223#	ch*	SCSI media changer
224#	cir*	Consumer IR
225#	clockctl clock control for non root users
226#	cpuctl	CPU control
227#	crypto	hardware crypto access driver
228#	dmoverio hardware-assisted data movers
229#	dpt*	DPT/Adaptec EATA RAID management interface
230#	dpti*	DPT/Adaptec I2O RAID management interface
231#	drm*	Direct Rendering Manager interface
232#	dtv*	Digital TV interface
233#	fb*	PMAX generic framebuffer pseudo-device
234#	fd	file descriptors
235#	gpiopps* 1PPS signals on GPIO pins
236#	grf*	graphics frame buffer device
237#	hdaudio* High Definition audio control device
238#	hdmicec* HDMI CEC devices
239#	hil	HP300 HIL input devices
240#	icp	ICP-Vortex/Intel RAID control interface
241#	iic*	IIC bus device
242#	io	x86 IOPL access for COMPAT_10, COMPAT_FREEBSD
243#	iop*	I2O IOP control interface
244#	ipmi*	OpenIPMI compatible interface
245#	ipl	IP Filter
246#	irframe* IrDA physical frame
247#	ite*	terminal emulator interface to HP300 graphics devices
248#	joy*	joystick device
249#	kttcp	kernel ttcp helper device
250#	lockstat kernel locking statistics
251#	magma*	Magma multiport serial/parallel cards
252#	midi*	MIDI
253#	mfi*	LSI MegaRAID/MegaSAS control interface
254#	mlx*	Mylex DAC960 control interface
255#	mly*	Mylex AcceleRAID/eXtremeRAID control interface
256#	np*	UNIBUS Ethernet co-processor interface, for downloading.
257#	npf	NPF packet filter
258#	nvme*	Non-Volatile Memory Host Controller Interface device driver
259#	nvme*ns* Non-Volatile Memory namespace
260#	nvmm	NetBSD Virtual Machine Monitor
261#	openfirm OpenFirmware accessor
262#	pad*	Pseudo-audio device driver
263#	pci*	PCI bus access devices
264#	pf	PF packet filter
265#	putter	Pass-to-Userspace Transporter
266#	px*	PixelStamp Xserver access
267#	qemufwcfg* QEMU Firmware Configuration
268#	radio*	radio devices
269#	random	Random number generator
270#	rtc*	RealTimeClock
271#	scmd*	Sparkfun Serial Controlled Motor Driver
272#	scsibus* SCSI busses
273#	se*	SCSI Ethernet
274#	ses*	SES/SAF-TE SCSI Devices
275#	sht3xtemp*	Sensirion SHT3X temperature and humidity device driver
276#	speaker	PC speaker		(XXX - installed)
277#	spi*	SPI bus device
278#	sram	battery backuped memory (x68k)
279#	srt*	source-address based routing
280#	ss*	SCSI scanner
281#	stic*	PixelStamp interface chip
282#	sysmon	System Monitoring hardware
283#	tap*	virtual Ethernet device
284#	tprof	task profiler
285#	tun*	network tunnel driver
286#	twa	3ware Apache control interface
287#	twe	3ware Escalade control interface
288#	uk*	unknown SCSI device
289#	veriexec Veriexec fingerprint loader
290#	vhci	virtual host controller interface
291#	video*	video capture devices
292#	view*	generic interface to graphic displays (Amiga)
293#	wsfont*	console font control
294#	wsmux*	wscons event multiplexor
295#	xenevt	Xen event interface
296#
297# iSCSI communication devices
298#	iscsi*	iSCSI driver and /sbin/iscsid communication
299#
300# Trusted Computing devices
301#	tpm	Trusted Platform Module
302#
303# Debugging and tracing
304#	dtrace	Dynamic tracing framework
305
306
307#
308# NOTE:
309#
310# * MAKEDEV is used both as a standalone script (via "sh ./MAKEDEV
311#   all" or similar), and as a function library for MAKEDEV.local (via
312#   "MAKEDEV_AS_LIBRARY=1 . MAKEDEV").  Because of this, the script
313#   should consist almost entirely of function definitions, apart from a
314#   few lines right at the end.
315#
316# * MAKEDEV may be executed in an environment that is missing some
317#   common commands.  For example, it may be executed from a minimal
318#   system used during installation, or it may be executed early in the
319#   boot sequence before most file systems have been mounted.  It may
320#   also be executed in a cross-build environment on a non-NetBSD host.
321#
322
323usage()
324{
325	cat 1>&2 << _USAGE_
326Usage: ${0##*/} [-fMsu] [-m mknod] [-p pax] [-t mtree] special [...]
327	Create listed special devices.  Options:
328	-f		Force permissions to be updated on existing devices.
329	-M		Create memory file system.
330	-m mknod	Name of mknod(8) program.  [\$TOOL_MKNOD or mknod]
331	-p pax  	Name of pax(1) program.  [\$TOOL_PAX or pax]
332	-s		Generate mtree(8) specfile instead of creating devices.
333	-t mtree	Name of mtree(8) program.  [\$TOOL_MTREE or mtree]
334	-u		Don't re-create devices that already exist.
335
336_USAGE_
337	exit 1
338}
339
340# zeropad width number
341#	display number with a zero (`0') padding of width digits.
342#
343zeropad()
344{
345	case $(($1 - ${#2})) in
346	5)	echo 00000$2;;
347	4)	echo 0000$2;;
348	3)	echo 000$2;;
349	2)	echo 00$2;;
350	1)	echo 0$2;;
351	0)	echo $2;;
352	*)	die "bad padding" ;;
353	esac
354}
355
356# hexprint number
357#	display (base10) number as hexadecimal
358#
359hexprint()
360{
361	val="$(($1 + 0))"
362	hex=
363	set -- 0 1 2 3 4 5 6 7 8 9 a b c d e f
364	while [ "$val" -gt 0 ]; do
365		eval hex=\${$(($val % 16 + 1))}\$hex
366		val="$(($val / 16))"
367	done
368	echo "${hex:-0}"
369}
370
371# linecount multiline_string
372#	count the number of lines in the string
373#
374linecount()
375{
376	local IFS='
377' # just a newline, no other white space between the quotes
378	set -- $1
379	echo $#
380}
381
382# nooutput -12 cmd [args...]
383#	run a command with stdout and/or stderr ignored.
384#	"nooutput -1 cmd" is like "cmd >/dev/null";
385#	"nooutput -2 cmd" is like "{ cmd ; } 2>/dev/null";
386#	"nooutput -12 cmd" is like "{ cmd ; } >/dev/null 2>&1";
387#	except they should work even if /dev/null doesn't [yet] exist.
388#
389#	The "{...}" wrapper used in cases where stderr is redirected
390#	serves to capture shell error messages such as "cmd: not found".
391#
392nooutput()
393{
394	local flags="$1" ; shift
395	local junk
396	case "$flags" in
397	"-1")	junk="$( "$@" )" ;;
398	"-2")	( exec 4>&1 ; junk="$( { "$@" ; } 2>&1 1>&4 )" ) ;;
399	"-12")	junk="$( { "$@" ; } 2>&1 )" ;;
400	*)	warn "Incorrect use of nooutput" ;;
401	esac
402}
403
404# check_pax path_to_pax
405#	Check whether pax exists and supports the command line options
406#	and input format that we will want to use.
407#
408check_pax()
409{
410	local pax="$1"
411	echo ". type=dir optional" | nooutput -12 "${pax}" -r -w -M -pe .
412}
413
414# check_mtree path_to_mtree
415#	Check whether mtree exists and supports the command line options
416#	and input format that we will want to use.
417#
418check_mtree()
419{
420	local mtree="$1"
421	echo ". type=dir optional" | nooutput -12 "${mtree}" -e -U
422}
423
424# setup args...
425#	Parse command line arguments, exit on error.
426#	Callers should shift $((OPTIND - 1)) afterwards.
427#
428setup()
429{
430	PATH=/sbin:/usr/sbin:/bin:/usr/bin:/rescue
431
432	: ${HOST_SH:=sh}
433	: ${TOOL_MKNOD:=mknod}
434	: ${TOOL_MTREE:=mtree}
435	: ${TOOL_PAX:=pax}
436	status=0
437	do_create_mfs=false
438	do_force=false
439	do_mknod=false
440	do_pax=false
441	do_mtree=false
442	do_redirect=false
443	do_specfile=false
444	do_update=false
445	opts=
446	while getopts Mfm:p:st:u ch; do
447		# Note that $opts is only for options passed through to
448		# MAKEDEV.local, not for all options.
449		case ${ch} in
450		M)
451			# "-M" sets do_create_mfs;
452			# "-M -M" is for use from init(8), and sets do_redirect
453			do_redirect=$do_create_mfs
454			do_create_mfs=true
455			;;
456		f)	do_force=true
457			opts="${opts} -f"
458			;;
459		m)	TOOL_MKNOD=${OPTARG}
460			do_mknod=true
461			opts="${opts} -m ${OPTARG}"
462			;;
463		p)	TOOL_PAX="${OPTARG}"
464			if check_pax "${TOOL_PAX}"; then
465				do_pax=true
466				# do not add this to $opts; we will later
467				# add "-s" instead.
468			else
469				warn "Ignored -p option:" \
470					"${TOOL_PAX} is missing or broken"
471				do_mknod=true
472			fi
473			;;
474		s)	do_specfile=true
475			opts="${opts} -s"
476			;;
477		t)	TOOL_MTREE="${OPTARG}"
478			if check_mtree "${TOOL_MTREE}"; then
479				do_mtree=true
480				# do not add this to $opts; we will later
481				# add "-s" instead.
482			else
483				warn "Ignored -t option:" \
484					"${TOOL_MTREE} is missing or broken"
485				do_mknod=true
486			fi
487			;;
488		u)
489			do_update=true
490			opts="${opts} -u"
491			;;
492		*)	usage ;;
493		esac
494	done
495
496	shift $((${OPTIND} - 1))
497	[ $# -gt 0 ] || usage
498
499	u_root="%uid_root%"
500	u_uucp="%uid_uucp%"
501	g_gpio="%gid__gpio%"
502	g_kmem="%gid_kmem%"
503	g_ntpd="%gid_ntpd%"
504	g_nvmm="%gid_nvmm%"
505	g_operator="%gid_operator%"
506	g_wheel="%gid_wheel%"
507	dialin=0
508	dialout=524288
509	callunit=262144
510
511	# only allow read&write for owner by default
512	umask 077
513
514	# Set fdesc_mounted=true if the fdesc file system is mounted
515	# on the current directory (typically "/dev").
516	# Later, this will be used to suppress creation of device nodes
517	# that are supplied by the fdesc file system.
518	#
519	fdesc_mounted=false
520	if [ -d fd ]; then
521		# Parse the output from "mount -u -o nosuchoption .".
522		# We don't parse the output from df(1) because that's
523		# less likely to be available on install media.
524		#
525		# If the current directory is a mount point for the
526		# fdesc file system, then the expected output (whether
527		# or not the current user is root) is:
528		#	mount_fdesc: -o suchoption: option not supported.
529		#
530		# If the current directory is not a mount point, then
531		# the expected output is:
532		#	mount: .: unknown special file or file system.
533		#
534		# If we are not running on NetBSD, or mount(8) is not
535		# found, then we should get some other error message.
536		#
537		case "$({ LC_ALL=C mount -u -o nosuchoption . ; } 2>&1)" in
538		*mount_fdesc*)	fdesc_mounted=true ;;
539		esac
540	fi
541
542	# do_force requires mknod
543	if $do_force; then
544		if $do_mtree || $do_pax || $do_specfile; then
545			die "-f option works only with mknod"
546		fi
547		do_mknod=true
548	fi
549
550	# do_force and do_update do not work together
551	if $do_force && $do_update; then
552		die "-f and -u options do not work together"
553	fi
554
555	# If no explicit method was specified on the command line or
556	# forced above, then use one of mtree, pax, or mknod, in that
557	# order of preference.
558	#
559	# mtree is preferred because it's fast and designed for the
560	# purpose.  However, it's unlikely to be available early in the
561	# boot sequence, when init(8) may invoke MAKEDEV(8).
562	#
563	# pax is usually acceptable, and it's likely to be available
564	# early in the boot sequence.  However, it's much slower than mtree.
565	#
566	# mknod is just very slow, because the shell has to fork for
567	# each device node.
568	#
569
570	case ",${do_mtree},,${do_pax},,${do_mknod},,${do_specfile}," in
571	( ,false,,false,,false,,false, )
572		if check_mtree "${TOOL_MTREE}"; then
573			do_mtree=true
574		elif check_pax "${TOOL_PAX}"; then
575			do_pax=true
576		else
577			do_mknod=true
578		fi
579		;;
580	( *,true,*,true,* )
581		die "-m, -p, -s, and -t options are mutually exclusive"
582		;;
583	esac
584
585	# If we are using mknod, then decide what options to pass it.
586	MKNOD="${TOOL_MKNOD:-mknod} -F netbsd"
587	if $do_mknod; then
588		if $do_force; then
589			MKNOD="${MKNOD} -R"
590		else
591			MKNOD="${MKNOD} -r"
592		fi
593	fi
594
595	# do_mtree or do_pax internally implies do_specfile.
596	# This happens after checking for mutually-exclusive options.
597	if $do_mtree || $do_pax && ! $do_specfile; then
598		do_specfile=true
599		opts="${opts} -s"
600	fi
601}
602
603# specfile_before
604#	This is called before the bulk of the makedev processing,
605#	if do_specfile is set.
606#
607#	It simply prints ". type=dir optional", which must be the
608#	first line of the specfile.
609#
610specfile_before()
611{
612	echo ". type=dir optional"
613}
614
615# mtree_after
616#	Output in specfile format is piped into this function.
617#
618#	It uses mtree to create the devices defined in the specfile.
619#
620mtree_after()
621{
622	nooutput -1 "${TOOL_MTREE}" -e -U
623}
624
625# pax_after
626#	Output in specfile format is piped into this function.
627#
628#	It uses pax to create the devices defined in the specfile.
629#
630pax_after()
631{
632	# Run pax in an empty directory, so it pays
633	# attention only to the specfile, without being
634	# confused by the existing contents of the target
635	# directory.  Without this, pax would complain "file
636	# would overwrite itself" for already-existing
637	# device nodes.
638	tmpdir=./tmp.$$
639	mkdir "${tmpdir}" || die "can't create temporary directory"
640	cd "${tmpdir}" || die "can't cd to temporary directory"
641	"${TOOL_PAX}" -r -w -M -pe ..
642	pax_status=$?
643	cd .. # back to where we started
644	rmdir "${tmpdir}"
645	return $pax_status
646}
647
648# makedev_main makedev_name args...
649#	Perform most of the work of the main program.  makedev_name
650#	is typically "makedev", but may be the name of some other
651#	makedev-like function (if we are invoked from MAKEDEV.local or
652#	some other script).  The other args to this function are the
653#	command line args with which the MAKEDEV (or MAKEDEV.local)
654#	script was invoked.
655#
656makedev_main()
657{
658	local makedev="$1" ; shift
659
660	# Parse command line args
661	setup ${1+"$@"}
662	shift $((${OPTIND}-1))
663
664	if $do_create_mfs; then
665		# Count inodes and create mfs file system.
666		# The makedev call merely updates $count_nodes.
667		count_nodes=0
668		$makedev ${1+"$@"}
669		create_mfs_dev $count_nodes
670		unset count_nodes
671	fi
672
673	# Set before, middle, and after variables, so we can do
674	# something like "( $before && $middle ) | $after",
675	# except it will have to be more complex so we can capture
676	# the exit status from both sides of the pipe.
677	#
678	if $do_specfile; then
679		before=specfile_before
680	else
681		before=:
682	fi
683	middle='$makedev ${1+"$@"} && (exit $status)'
684	if $do_mtree; then
685		after=mtree_after
686	elif $do_pax ; then
687		after=pax_after
688	else
689		after=cat
690	fi
691
692	# Actually perform the "{ $before && $middle } | $after" commands.
693	#
694	# We go to some trouble to ensure that, if any of
695	# $before, $middle, or $after fails, then we also
696	# exit with a non-zero status.
697	#
698	# In the block below, fd 3 is a copy of the original stdout,
699	# and fd 4 goes to a subshell that analyses the exit status
700	# status from the other commands.
701	#
702	{
703		exec 3>&1;
704		{
705			{ eval "$before" && eval "$middle"; echo $? >&4; } \
706			| { eval "$after"; echo $? >&4; } \
707		} 4>&1 1>&3 \
708		| (
709			read status1;
710			read status2;
711			case "$status1,$status2" in
712			0,0) exit 0;;
713			0,*) exit $status2;;
714			*,*) exit $status1;;
715			esac
716		)
717	}
718}
719
720#
721# functions available to create nodes:
722#
723# mkdev name [b|c] major minor [mode{=600} [gid{=0} [uid{=0}]]]
724#	create device node `name' with the appropriate permissions
725#
726# lndev src target
727#	create a symlink from src to target
728#
729# makedir dir mode
730#	create directory with appropriate mode
731#
732
733mkdev()
734{
735	if [ -n "$count_nodes" ]; then
736		count_nodes=$((count_nodes + 1))
737		return
738	fi
739	if $do_update && test -e $1; then
740		return
741	fi
742	if $do_specfile; then
743		case $2 in
744		b)	type=block ;;
745		c)	type=char ;;
746		esac
747		echo "./$1 type=${type} device=netbsd,$3,$4 mode=${5:-600} gid=${6:-$g_wheel} uid=${7:-$u_root}"
748	else
749		${MKNOD} -m ${5:-600} -g \#${6:-$g_wheel} -u \#${7:-$u_root} $1 $2 $3 $4
750	fi
751}
752
753lndev()
754{
755	if [ -n "$count_nodes" ]; then
756		count_nodes=$((count_nodes + 1))
757		return
758	fi
759	if $do_update && test -e $2; then
760		return
761	fi
762	if $do_specfile; then
763		echo "./$2 type=link link=$1 mode=0700 gid=$g_wheel uid=$u_root"
764	else
765		ln -f -s $1 $2
766	fi
767}
768
769makedir()
770{
771	if [ -n "$count_nodes" ]; then
772		count_nodes=$((count_nodes + 1))
773		return
774	fi
775	if $do_update && test -e $1; then
776		return
777	fi
778	if $do_specfile; then
779		echo "./$1 type=dir mode=$2 gid=$g_wheel uid=$u_root"
780	else
781		nooutput -2 mkdir $1
782		chmod $2 $1
783	fi
784}
785
786warn()
787{
788	echo 1>&2 "$0: $*"
789	status=1
790}
791
792die()
793{
794	echo 1>&2 "$0: $*"
795	exit 1
796}
797
798# makedev special [...]
799#	the main loop
800#
801makedev()
802{
803
804for i
805do
806
807case $i in
808
809%MD_DEVICES%
810
811all)
812	makedev all_md
813	makedev std fd ptm
814	makedev dk0 dk1 dk2 dk3 dk4 dk5 dk6 dk7
815	makedev dk8 dk9 dk10 dk11 dk12 dk13 dk14 dk15
816	makedev dk16 dk17 dk18 dk19 dk20 dk21 dk22 dk23
817	makedev dk24 dk25 dk26 dk27 dk28 dk29 dk30 dk31
818	makedev ccd0 ccd1 ccd2 ccd3
819	makedev cgd0 cgd1 cgd2 cgd3 cgd4 cgd5 cgd6 cgd7
820	makedev fss0 fss1 fss2 fss3
821	makedev md0 md1
822	makedev raid0 raid1 raid2 raid3 raid4 raid5 raid6 raid7
823	makedev vnd0 vnd1 vnd2 vnd3
824	makedev iscsi0
825	makedev bpf npf
826	makedev tun0 tun1 tun2 tun3
827	makedev ipl pf crypto random
828	makedev lockstat clockctl cpuctl
829	makedev atabus0 atabus1 atabus2 atabus3 atabus4 atabus5 atabus6 atabus7
830	makedev srt0 srt1 srt2 srt3
831	makedev tap tap0 tap1 tap2 tap3
832	makedev gpio gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
833	makedev gpiopps0
834	makedev pad pad0 pad1 pad2 pad3
835	makedev bthub
836	makedev putter
837	makedev drvctl
838	makedev video
839	makedev dtv
840	makedev drm0 drm1 drm2 drm3
841	makedev altmem
842	makedev zfs
843	makedev lua
844	makedev hdmicec0
845	makedev dtrace
846	makedev veriexec
847	makedev autofs
848	makedev fw0 fw1 fw2 fw3
849	makedev ipmi0
850	makedev qemufwcfg
851	makedev sht3xtemp0
852	makedev scmd0
853	makedev local # do this last
854	;;
855
856init)
857	# unless overridden by MD entry, this is equal to 'all'
858	makedev all opty
859	;;
860
861%MI_DEVICES_BEGIN%
862audio)
863	makedev audio0 audio1 audio2 audio3
864	makedev hdaudio0 hdaudio1 hdaudio2 hdaudio3
865	lndev sound0 sound
866	lndev audio0 audio
867	lndev mixer0 mixer
868	lndev audioctl0 audioctl
869	;;
870
871gpio)
872	makedev gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
873	lndev gpio0 gpio
874	;;
875
876gpiopps)
877	makedev gpiopps0
878	lndev gpiopps0 gpiopps
879	;;
880
881lua)
882	makedev lua0
883	lndev lua0 lua
884	;;
885
886pad)
887	makedev pad0 pad1 pad2 pad3
888	lndev pad0 pad
889	;;
890
891qemufwcfg)
892	makedev qemufwcfg0
893	lndev qemufwcfg0 qemufwcfg
894	;;
895
896radio)
897	makedev radio0 radio1
898	lndev radio0 radio
899	;;
900
901video)
902	makedev video0 video1 video2 video3
903	;;
904
905dtv)
906	makedev dtv0 dtv1 dtv2 dtv3
907	;;
908
909iic)
910	makedev iic0 iic1 iic2 iic3
911	;;
912
913altmem)
914	makedev altmem0 altmem1
915	;;
916
917ramdisk)
918	makedev floppy md0
919	;;
920
921sht3xtemp)
922    	makedev sht3xtemp0
923    	;;
924
925scmd)
926    	makedev scmd0
927    	;;
928
929usbs)
930	makedev usb usb0 usb1 usb2 usb3 usb4 usb5 usb6 usb7
931	makedev usb8 usb9 usb10 usb11 usb12 usb13 usb14 usb15
932	makedev uhid0 uhid1 uhid2 uhid3 uhid4 uhid5
933	makedev uhid6 uhid7 uhid8 uhid9 uhid10 uhid11
934	makedev uhid12 uhid13 uhid14 uhid15
935	makedev ulpt0 ulpt1
936	makedev ttyU0 ttyU1 ttyU2 ttyU3 ttyU4 ttyU5 ttyU6 ttyU7
937	makedev ttyY0 ttyY1
938	makedev ttyHS0
939	makedev utoppy0 utoppy1
940	makedev ugen0 ugen1 ugen2 ugen3
941	;;
942
943std)
944	mkdev		console c %cons_chr% 0	600
945	mkdev		constty c %cons_chr% 1	600
946	mkdev		drum	c %swap_chr% 0	640 $g_kmem
947	mkdev		kmem	c %mem_chr% 1	640 $g_kmem
948	mkdev		mem	c %mem_chr% 0	640 $g_kmem
949	mkdev		null	c %mem_chr% 2	666
950	mkdev		full	c %mem_chr% 11	666
951	mkdev		zero	c %mem_chr% 12	666
952	mkdev		klog	c %log_chr% 0	600
953	mkdev		ksyms	c %ksyms_chr% 0 440 $g_kmem
954	mkdev		random	c %rnd_chr% 0	444
955	mkdev		urandom	c %rnd_chr% 1	644
956	if ! $fdesc_mounted; then
957		mkdev	tty	c %ctty_chr% 0		666
958		mkdev	stdin	c %filedesc_chr% 0	666
959		mkdev	stdout	c %filedesc_chr% 1	666
960		mkdev	stderr	c %filedesc_chr% 2	666
961	fi
962	;;
963
964usb)
965	mkdev usb c %usb_chr% 255 444
966	;;
967
968usb[0-9]*)
969	unit=${i#usb}
970	usb=usb$unit
971	mkdev usb$unit c %usb_chr% $unit
972	;;
973
974uhid[0-9]*)
975	unit=${i#uhid}
976	mkdev uhid$unit c %uhid_chr% $unit 666
977	;;
978
979ulpt[0-9]*)
980	unit=${i#ulpt}
981	mkdev ulpt$unit c %ulpt_chr% $unit
982	mkdev ulpn$unit c %ulpt_chr% $(($unit + 64))
983	;;
984
985utoppy[0-9]*)
986	unit=${i#utoppy}
987	mkdev utoppy$unit c %utoppy_chr% $unit
988	;;
989
990ttyHS[0-9]*)
991	unit=${i#ttyHS}
992	for j in 00 01 02 03 04 05 06 07 08 09 10
993	do
994		base=$(($unit * 16 + ${j#0}))
995		mkdev ttyHS$unit.$j c %uhso_chr% $(($base + $dialin  )) "" "" $u_uucp
996		mkdev dtyHS$unit.$j c %uhso_chr% $(($base + $dialout )) "" "" $u_uucp
997		mkdev ctyHS$unit.$j c %uhso_chr% $(($base + $callunit)) "" "" $u_uucp
998	done
999	;;
1000
1001ttyY[0-9]*)
1002	unit=${i#ttyY}
1003	mkdev ttyY$unit c %ucycom_chr% $(($unit + $dialin  )) "" "" $u_uucp
1004	mkdev dtyY$unit c %ucycom_chr% $(($unit + $dialout )) "" "" $u_uucp
1005	mkdev ctyY$unit c %ucycom_chr% $(($unit + $callunit)) "" "" $u_uucp
1006	;;
1007
1008ucom[0-9]*)
1009	makedev ttyU${i#ucom}
1010	;;
1011
1012ttyU[0-9]*)
1013	unit=${i#ttyU}
1014	mkdev ttyU$unit c %ucom_chr% $(($unit + $dialin	 )) "" "" $u_uucp
1015	mkdev dtyU$unit c %ucom_chr% $(($unit + $dialout )) "" "" $u_uucp
1016	mkdev ctyU$unit c %ucom_chr% $(($unit + $callunit)) "" "" $u_uucp
1017	;;
1018
1019ugen[0-9]*)
1020	unit=${i#ugen}
1021	for j in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
1022	do
1023		mkdev ugen$unit.$j c %ugen_chr% $(($unit * 16 + ${j#0}))
1024	done
1025	;;
1026
1027wscons)
1028	makedev ttyE0 ttyE1 ttyE2 ttyE3 ttyE4 ttyE5 ttyE6 ttyE7
1029	makedev ttyF0 ttyF1 ttyF2 ttyF3 ttyF4 ttyF5 ttyF6 ttyF7
1030	makedev ttyG0 ttyG1 ttyG2 ttyG3 ttyG4 ttyG5 ttyG6 ttyG7
1031	makedev ttyH0 ttyH1 ttyH2 ttyH3 ttyH4 ttyH5 ttyH6 ttyH7
1032	makedev wsmouse0 wsmouse1 wsmouse2 wsmouse3
1033	makedev wskbd0 wskbd1 wskbd2 wskbd3
1034	makedev wsmux0 wsmux1 wsmux2 wsmux3
1035	makedev wsmouse wskbd
1036	makedev ttyEcfg ttyEstat
1037	makedev ttyFcfg ttyFstat
1038	makedev ttyGcfg ttyGstat
1039	makedev ttyHcfg ttyHstat
1040	makedev wsfont
1041	;;
1042
1043wsmouse)
1044	mkdev wsmouse c %wsmux_chr% 0
1045	;;
1046
1047wskbd)
1048	mkdev wskbd c %wsmux_chr% 1
1049	;;
1050
1051wsmux[0-9]*)
1052	unit=${i#wsmux}
1053	mkdev wsmux$unit    c %wsmux_chr% $unit
1054	mkdev wsmuxctl$unit c %wsmux_chr% $(($unit + 128)) 200
1055	;;
1056
1057xenevt)
1058	mkdev xenevt c %xenevt_chr% 0
1059	;;
1060
1061xsd_kva)
1062	mkdev xsd_kva c %xenevt_chr% 1
1063	;;
1064
1065xencons)
1066	mkdev xencons c %xencons_chr% 0
1067	;;
1068
1069ttyEstat)
1070	mkdev ttyEstat c %wsdisplay_chr% 254
1071	;;
1072
1073ttyEcfg)
1074	mkdev ttyEcfg c %wsdisplay_chr% 255
1075	;;
1076
1077ttyE[0-9]*)
1078	unit=${i#ttyE}
1079	mkdev ttyE$unit c %wsdisplay_chr% $unit
1080	;;
1081
1082ttyFstat)
1083	mkdev ttyFstat c %wsdisplay_chr% 510
1084	;;
1085
1086ttyFcfg)
1087	mkdev ttyFcfg c %wsdisplay_chr% 511
1088	;;
1089
1090ttyF[0-9]*)
1091	unit=${i#ttyF}
1092	mkdev ttyF$unit c %wsdisplay_chr% $(($unit + 256))
1093	;;
1094
1095ttyGstat)
1096	mkdev ttyGstat c %wsdisplay_chr% 766
1097	;;
1098
1099ttyGcfg)
1100	mkdev ttyGcfg c %wsdisplay_chr% 767
1101	;;
1102
1103ttyG[0-9]*)
1104	unit=${i#ttyG}
1105	mkdev ttyG$unit c %wsdisplay_chr% $(($unit + 512))
1106	;;
1107
1108ttyHstat)
1109	mkdev ttyHstat c %wsdisplay_chr% 1022
1110	;;
1111
1112ttyHcfg)
1113	mkdev ttyHcfg c %wsdisplay_chr% 1023
1114	;;
1115
1116ttyH[0-9]*)
1117	unit=${i#ttyH}
1118	mkdev ttyH$unit c %wsdisplay_chr% $(($unit + 768))
1119	;;
1120
1121wsmouse[0-9]*)
1122	unit=${i#wsmouse}
1123	mkdev wsmouse$unit c %wsmouse_chr% $unit
1124	;;
1125
1126wskbd[0-9]*)
1127	unit=${i#wskbd}
1128	mkdev wskbd$unit c %wskbd_chr% $unit
1129	;;
1130
1131fd)
1132	if ! $fdesc_mounted; then
1133		# Create the "fd" subdirectory, and devices "fd/0" to "fd/63"
1134		makedir fd 755
1135		n=0
1136		while [ $n -lt 64 ]
1137		do
1138			mkdev fd/$n c %filedesc_chr% $n 666
1139			n=$(($n + 1))
1140		done
1141	fi
1142	;;
1143
1144wt[0-9]*)
1145	name=wt;  unit=${i#wt};	chr=%wt_chr%;	blk=%wt_blk%
1146	for sub in $unit $(($unit+8)) $(($unit+16))
1147	do
1148		mkdev $name$sub		b $blk $(($sub + 0)) 660 $g_operator
1149		mkdev n$name$sub	b $blk $(($sub + 4)) 660 $g_operator
1150		mkdev r$name$sub	c $chr $(($sub + 0)) 660 $g_operator
1151		mkdev nr$name$sub	c $chr $(($sub + 4)) 660 $g_operator
1152	done
1153	;;
1154
1155md[0-9]*)
1156	makedisk_minimal md ${i#md} %md_blk% %md_chr%
1157	;;
1158
1159fss[0-9]*)
1160	name=fss; unit=${i#fss};	blk=%fss_blk%;	chr=%fss_chr%
1161	mkdev $name$unit	b $blk $unit 660 $g_operator
1162	mkdev r$name$unit	c $chr $unit 660 $g_operator
1163	;;
1164
1165ss[0-9]*)
1166	name=ss;	unit=${i#ss};	chr=%ss_chr%
1167	mkdev $name$unit	c $chr $(($unit * 16 + 0)) 640 $g_operator
1168	mkdev n$name$unit	c $chr $(($unit * 16 + 1)) 640 $g_operator
1169	mkdev en$name$unit	c $chr $(($unit * 16 + 3)) 640 $g_operator
1170	;;
1171
1172ccd[0-9]*|cgd[0-9]*|raid[0-9]*|vnd[0-9]*)
1173	case $i in
1174	ccd*)	name=ccd;	unit=${i#ccd};	blk=%ccd_blk%;	chr=%ccd_chr%;;
1175	cgd*)	name=cgd;	unit=${i#cgd};	blk=%cgd_blk%;	chr=%cgd_chr%;;
1176	raid*)	name=raid;	unit=${i#raid}; blk=%raid_blk%; chr=%raid_chr%;;
1177	vnd*)	name=vnd;	unit=${i#vnd};	blk=%vnd_blk%;	chr=%vnd_chr%;;
1178	esac
1179	%MKDISK% $name $unit $blk $chr
1180	;;
1181
1182sd[0-9]*)
1183	name=sd; unit=${i#sd};	blk=%sd_blk%;	chr=%sd_chr%
1184	%MKDISK% $name $unit $blk $chr
1185	;;
1186
1187ace[0-9]*)
1188	name=ace; unit=${i#ace};	blk=%ace_blk%;		chr=%ace_chr%
1189	%MKDISK% $name $unit $blk $chr
1190	;;
1191
1192eflash[0-9]*)
1193	name=eflash; unit=${i#eflash};	blk=%eflash_blk%;	chr=%eflash_chr%
1194	%MKDISK% $name $unit $blk $chr
1195	;;
1196
1197wd[0-9]*)
1198	name=wd; unit=${i#wd}; blk=%wd_blk%; chr=%wd_chr%
1199	%MKDISK% $name $unit $blk $chr
1200	;;
1201
1202fd[0-9]*)
1203	name=fd; unit=${i#fd}; blk=%fd_blk%; chr=%fd_chr%
1204	%MKDISK% $name $unit $blk $chr
1205	;;
1206
1207ld[0-9]*)
1208	name=ld; unit=${i#ld}; blk=%ld_blk%; chr=%ld_chr%
1209	%MKDISK% $name $unit $blk $chr
1210	;;
1211
1212flash[0-9]*)
1213	unit=${i#flash}
1214	flash=flash$unit
1215	mkdev flash$unit b %flash_blk% $unit
1216	mkdev rflash$unit c %flash_chr% $unit
1217	;;
1218
1219spiflash[0-9]*)
1220	unit=${i#spiflash}
1221	spiflash=spiflash$unit
1222	mkdev spiflash$unit b %spiflash_blk% $unit
1223	mkdev rspiflash$unit c %spiflash_chr% $unit
1224	;;
1225
1226altmem[0-9]*)
1227	name=altmem; unit=${i#altmem}; blk=%altmem_blk%; chr=%altmem_chr%
1228	%MKDISK% $name $unit $blk $chr
1229	;;
1230
1231bio)
1232	mkdev bio c %bio_chr% 0
1233	;;
1234
1235ed[0-9]*)
1236	name=ed; unit=${i#ed}; blk=%ed_blk%; chr=%ed_chr%
1237	%MKDISK% $name $unit $blk $chr
1238	;;
1239
1240ofdisk[0-9]*)
1241	name=ofdisk; unit=${i#ofdisk}; blk=%ofdisk_blk%; chr=%ofdisk_chr%
1242	%MKDISK% $name $unit $blk $chr
1243	;;
1244
1245xbd[0-9]*)
1246	name=xbd; unit=${i#xbd}; blk=%xbd_blk%; chr=%xbd_chr%
1247	%MKDISK% $name $unit $blk $chr
1248	;;
1249
1250dk[0-9]*)
1251	name=dk; unit=${i#dk}; blk=%dk_blk%; chr=%dk_chr%
1252	mkdev r$name$unit c $chr $unit 0640 $g_operator
1253	mkdev $name$unit b $blk  $unit 0640 $g_operator
1254	;;
1255
1256tprof)
1257	mkdev tprof c %tprof_chr% 0
1258	;;
1259
1260ttyCY[0-9]*)
1261	# Each unit number creates 32 pairs of {tty,dty} device nodes:
1262	# ttyCY0 => device nodes [td]tyCY000 to [td]tyCY031;
1263	# ttyCY1 => device nodes [td]tyCY032 to [td]tyCY063;
1264	name=tyCY; chr=%cy_chr%; off=32
1265	unit=${i#t${name}}
1266	minor=$(($unit * $off))
1267	eminor=$(($minor + $off))
1268	while [ $minor -lt $eminor ]
1269	do
1270		nminor=000$minor
1271		nminor=${nminor#${nminor%???}}
1272		mkdev t$name$nminor c $chr $(($minor + $dialin )) "" "" $u_uucp
1273		mkdev d$name$nminor c $chr $(($minor + $dialout)) "" "" $u_uucp
1274		minor=$(($minor + 1))
1275	done
1276	;;
1277
1278ttyCZ[0-9]*)
1279	# Each unit number creates 64 pairs of {tty,dty} device nodes:
1280	# ttyCZ0 => device nodes [td]tyCZ0000 to [td]tyCZ0063;
1281	# ttyCZ1 => device nodes [td]tyCZ0064 to [td]tyCZ0127;
1282	name=tyCZ; chr=%cz_chr%; off=64
1283	unit=${i#t${name}}
1284	minor=$(($unit * $off))
1285	eminor=$(($minor + $off))
1286	while [ $minor -lt $eminor ]
1287	do
1288		nminor=0000$minor
1289		nminor=${nminor#${nminor%????}}
1290		mkdev t$name$nminor c $chr $(($minor + $dialin )) "" "" $u_uucp
1291		mkdev d$name$nminor c $chr $(($minor + $dialout)) "" "" $u_uucp
1292		minor=$(($minor + 1))
1293	done
1294	;;
1295
1296
1297tty[0-9]|tty0[0-9])
1298	# some archs have built-in zstty (major %zstty_chr%) instead
1299	# of NS16550; create ttyZ* and hardlink as [dt]ty0*; this
1300	# needs to be before com entry, for archs which have both
1301	unit=${i#tty}
1302	unit=$(($unit + 0))
1303	makedev ttyZ${unit}
1304	lndev ttyZ$unit tty0${unit}
1305	lndev dtyZ$unit dty0${unit}
1306	;;
1307
1308tty[0-9]*)
1309	unit=${i#tty}
1310	ounit=00$unit
1311	ounit=${ounit#${ounit%??}}
1312	mkdev tty$ounit c %com_chr% $(($unit + $dialin )) "" "" $u_uucp
1313	mkdev dty$ounit c %com_chr% $(($unit + $dialout)) "" "" $u_uucp
1314	;;
1315
1316ttyC[0-9]*)
1317		# some archs call com_chr ttyC traditionally
1318	unit=${i#ttyC}; name=ttyC; dname=dtyC; chr=%com_chr%
1319	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1320	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1321	;;
1322
1323ttyh[0-9]*)
1324	unit=${i#ttyh}; name=ttyh; dname=dtyh; chr=%sabtty_chr%
1325	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1326	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1327	;;
1328
1329ttyTX[0-9]*)
1330	unit=${i#ttyTX}; name=ttyTX0; dname=dtyTX0; chr=%txcom_chr%
1331	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1332	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1333	;;
1334
1335ttyZ[0-9]*)
1336	unit=${i#ttyZ}; name=ttyZ; dname=dtyZ; chr=%zstty_chr%
1337	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1338	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1339	;;
1340
1341opty)
1342	# Create 16 device nodes, [pt]typ0 to [pt]typf,
1343	# same as "MAKEDEV pty0".
1344	for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f
1345	do
1346		case $j in
1347		[0-9])	jn=$j ;;
1348		a)	jn=10 ;;
1349		b)	jn=11 ;;
1350		c)	jn=12 ;;
1351		d)	jn=13 ;;
1352		e)	jn=14 ;;
1353		f)	jn=15 ;;
1354		esac
1355		mkdev ttyp$j c %pts_chr% $jn 666
1356		mkdev ptyp$j c %ptc_chr% $jn 666
1357	done
1358	;;
1359
1360pty[0-9]*)
1361	# Each unit number creates up to 16 pairs of {tty,pty} device nodes:
1362	# pty0 => 16 pairs, [tp]typ0 to [tp]typf
1363	# pty1 => 16 pairs, [tp]tyq0 to [tp]tyqf
1364	# pty16 => 16 pairs, [tp]typg to [tp]typv
1365	# pty17 => 16 pairs, [tp]typw to [tp]typL
1366	# pty18 => 14 pairs, [tp]typM to [tp]typZ
1367	warn "$i: creating BSD style tty nodes with ptyfs is a security issue"
1368	class=${i#pty}
1369	d1="p q r s t u v w x y z P Q R S T"
1370	if [ "$class" -ge 64 ]
1371	then
1372		warn "$i: pty unit must be between 0 and 63"
1373		continue
1374	elif [ "$class" -lt 16 ]
1375	then
1376		# pty[p-zP-T][0-9a-f]
1377		offset=0
1378		mult=0
1379		d2="0 1 2 3 4 5 6 7 8 9 a b c d e f"
1380	else
1381		# pty[p-zP-T][g-zA-Z]
1382		class=$(($class - 16))
1383		offset=256
1384		mult=2
1385		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"
1386	fi
1387	start=$(($class * 16))
1388	set -- $d2
1389	nt=$#
1390	s1=$(($start / $nt))
1391	set -- $d1
1392	shift $s1
1393	t1=$1
1394	if [ "$t1" = v ]; then
1395		warn "$i: pty unit conflicts with console ttyv0 device"
1396		continue
1397	fi
1398	s2=$(($start % ($nt - $s1 * $mult)))
1399	set -- $d2
1400	shift $s2
1401	t2=$1
1402	unit=$(($start + $offset - $s1 * $mult))
1403	end=$(($unit + 16))
1404	while [ "$unit" -lt "$end" ]
1405	do
1406		mkdev tty$t1$t2 c %pts_chr% $unit 666
1407		mkdev pty$t1$t2 c %ptc_chr% $unit 666
1408		shift
1409		t2=$1
1410		if [ -z "$t2" ]
1411		then
1412			break
1413		fi
1414		unit=$(($unit + 1))
1415	done
1416	;;
1417
1418stic[0-9]*)
1419	unit=${i#stic}
1420	mkdev stic$unit c %stic_chr% $unit
1421	;;
1422
1423st[0-9]*)
1424	name=st;	unit=${i#st};	chr=%st_chr%;	blk=%st_blk%
1425	mkdev $name$unit	b $blk $(($unit * 16 + 0)) 660 $g_operator
1426	mkdev n$name$unit	b $blk $(($unit * 16 + 1)) 660 $g_operator
1427	mkdev e$name$unit	b $blk $(($unit * 16 + 2)) 660 $g_operator
1428	mkdev en$name$unit	b $blk $(($unit * 16 + 3)) 660 $g_operator
1429	mkdev r$name$unit	c $chr $(($unit * 16 + 0)) 660 $g_operator
1430	mkdev nr$name$unit	c $chr $(($unit * 16 + 1)) 660 $g_operator
1431	mkdev er$name$unit	c $chr $(($unit * 16 + 2)) 660 $g_operator
1432	mkdev enr$name$unit	c $chr $(($unit * 16 + 3)) 660 $g_operator
1433	;;
1434
1435ses[0-9]*|ch[0-9]*|uk[0-9]*)
1436	case $i in
1437	ch*)	name=ch;	unit=${i#ch};	chr=%ch_chr%;;
1438	uk*)	name=uk;	unit=${i#uk};	chr=%uk_chr%;;
1439	ses*)	name=ses;	unit=${i#ses};	chr=%ses_chr%;;
1440	esac
1441	mkdev $name$unit c $chr $unit 640 $g_operator
1442	;;
1443
1444cd[0-9]*)
1445	makedisk_minimal cd ${i#cd} %cd_blk% %cd_chr%
1446	;;
1447
1448mcd[0-9]*)
1449	makedisk_minimal mcd ${i#mcd} %mcd_blk% %mcd_chr%
1450	;;
1451
1452gdrom[0-9]*)
1453	makedisk_minimal gdrom ${i#gdrom} %gdrom_blk% %gdrom_chr%
1454	;;
1455
1456lpt[0-9]*|lpa[0-9]*)
1457	case $i in
1458	lpt*) name=lpt; unit=${i#lpt};	chr=%lpt_chr%;	flags=0;;
1459	lpa*) name=lpa; unit=${i#lpa};	chr=%lpt_chr%;	flags=128;;
1460	esac
1461	mkdev $name$unit c $chr $(($unit + $flags))
1462	mkdev lpt${unit}ctl c $chr $(($unit + 256))
1463	;;
1464
1465bpf)
1466	mkdev bpf	c %bpf_chr% 0
1467	lndev bpf bpf0
1468	;;
1469
1470npf)
1471	mkdev npf	c %npf_chr% 0
1472	;;
1473
1474bthub)
1475	mkdev bthub c %bthub_chr% 0
1476	;;
1477
1478tun[0-9]*)
1479	unit=${i#tun}
1480	mkdev tun$unit c %tun_chr% $unit
1481	;;
1482
1483joy[0-9]*)
1484	unit=${i#joy}
1485	mkdev joy$unit c %joy_chr% $unit
1486	;;
1487
1488ipl)
1489	mkdev ipl	c %ipl_chr% 0
1490	mkdev ipnat	c %ipl_chr% 1
1491	mkdev ipstate	c %ipl_chr% 2
1492	mkdev ipauth	c %ipl_chr% 3
1493	mkdev ipsync	c %ipl_chr% 4
1494	mkdev ipscan	c %ipl_chr% 5
1495	mkdev iplookup	c %ipl_chr% 6
1496	;;
1497
1498pf)
1499	mkdev pf c %pf_chr% 0
1500	;;
1501
1502crypto)
1503	mkdev crypto c %crypto_chr% 0 666
1504	;;
1505
1506cmos)
1507	mkdev cmos c %cmos_chr% 0 644
1508	;;
1509
1510speaker)
1511	mkdev speaker c %spkr_chr% 0
1512	;;
1513
1514lockstat)
1515	mkdev lockstat c %lockstat_chr% 0
1516	;;
1517
1518cpuctl)
1519	mkdev cpuctl c %cpuctl_chr% 0 666
1520	;;
1521
1522audio|audio[0-9]*)
1523	unit=${i#audio}
1524	audio=audio$unit
1525	sound=sound$unit
1526	mixer=mixer$unit
1527	audioctl=audioctl$unit
1528	: ${unit:-0}
1529	mkdev $sound	c %audio_chr% $(($unit + 0))	666
1530	mkdev $audio	c %audio_chr% $(($unit + 128))	666
1531	mkdev $mixer	c %audio_chr% $(($unit + 16))	666
1532	mkdev $audioctl c %audio_chr% $(($unit + 192))	666
1533	;;
1534
1535hdaudio[0-9]*)
1536	unit=${i#hdaudio}
1537	mkdev hdaudio$unit c %hdaudio_chr% $unit 644
1538	;;
1539
1540hdmicec[0-9]*)
1541	uint=${i#hdmicec}
1542	mkdev hdmicec$unit c %hdmicec_chr% $unit 644
1543	;;
1544
1545gpio[0-9]*)
1546	unit=${i#gpio}
1547	mkdev gpio$unit c %gpio_chr% $unit 664 $g_gpio
1548	;;
1549
1550gpiopps[0-9]*)
1551	unit=${i#gpiopps}
1552	mkdev gpiopps$unit c %gpiopps_chr% $unit 664 $g_gpio
1553	;;
1554
1555lua[0-9]*)
1556	unit=${i#lua}
1557	mkdev lua$unit c %lua_chr% $unit 664
1558	;;
1559
1560rmidi[0-9]*)
1561	unit=${i#rmidi}
1562	mkdev rmidi$unit c %midi_chr% $unit 666
1563	;;
1564
1565music|music[0-9]*)
1566	unit=${i#music}
1567	: ${unit:-0}
1568	mkdev music$unit     c %sequencer_chr% $(($unit + 0))	666
1569	mkdev sequencer$unit c %sequencer_chr% $(($unit + 128)) 666
1570	;;
1571
1572radio|radio[0-9]*)
1573	unit=${i#radio}
1574	: ${unit:-0}
1575	mkdev radio$unit c %radio_chr% $unit 666
1576	;;
1577
1578video|video[0-9]*)
1579	unit=${i#video}
1580	: ${unit:-0}
1581	mkdev video$unit c %video_chr% $unit 666
1582	;;
1583
1584dtv[0-9]*)
1585	unit=${i#dtv}
1586	makedir dvb 755
1587	makedir dvb/adapter$unit 755
1588	mkdev dvb/adapter$unit/frontend0 c %dtv_chr% $(($unit + 0)) 666
1589	mkdev dvb/adapter$unit/demux0 c %dtv_chr% $(($unit + 16)) 666
1590	mkdev dvb/adapter$unit/dvr0 c %dtv_chr% $(($unit + 32)) 666
1591	;;
1592
1593iic[0-9]*)
1594	unit=${i#iic}
1595	: ${unit:-0}
1596	mkdev iic$unit c %iic_chr% $unit 600
1597	;;
1598
1599spi[0-9]*)
1600	unit=${i#spi}
1601	: ${unit:-0}
1602	mkdev spi$unit c %spi_chr% $unit 600
1603	;;
1604
1605amr[0-9]*)
1606	unit=${i#amr}
1607	mkdev amr$unit c %amr_chr% $unit
1608	;;
1609
1610apm)
1611	mkdev apm	c %apm_chr% 0 644
1612	mkdev apmctl	c %apm_chr% 8 644
1613	;;
1614
1615apm)
1616		# hpcmips uses `apmdev_chr' instead of `apm_chr'
1617	mkdev apm	c %apmdev_chr% 0 644
1618	mkdev apmctl	c %apmdev_chr% 8 644
1619	;;
1620
1621random)
1622	mkdev random	c %rnd_chr% 0 444
1623	mkdev urandom	c %rnd_chr% 1 644
1624	;;
1625
1626cfs)
1627	makedev cfs0
1628	;;
1629
1630cfs[0-9]*)
1631	unit=${i#cfs}
1632	mkdev cfs$unit c %vcoda_chr% $unit
1633	;;
1634
1635sysmon)
1636	mkdev sysmon	c %sysmon_chr% 0 644
1637	mkdev watchdog	c %sysmon_chr% 1 644
1638	mkdev power	c %sysmon_chr% 2 640
1639	;;
1640
1641scsibus[0-9]*)
1642	unit=${i#scsibus}
1643	mkdev scsibus$unit c %scsibus_chr% $unit 644
1644	;;
1645
1646bktr)
1647	makedev bktr0 bktr1
1648	lndev	bktr0	bktr
1649	lndev	tuner0	tuner
1650	lndev	vbi0	vbi
1651	;;
1652
1653bktr[0-9]*)
1654	unit=${i#bktr}
1655	mkdev bktr$unit		c %bktr_chr% $(($unit + 0))	444
1656	mkdev tuner$unit	c %bktr_chr% $(($unit + 16))	444
1657	mkdev vbi$unit		c %bktr_chr% $(($unit + 32))	444
1658	;;
1659
1660io)
1661	mkdev		io	c %mem_chr% 14	600
1662	;;
1663
1664iop[0-9]*)
1665	unit=${i#iop}
1666	mkdev iop$unit c %iop_chr% $unit
1667	;;
1668
1669mfi[0-9]*)
1670	unit=${i#mfi}
1671	mkdev mfi$unit c %mfi_chr% $unit
1672	;;
1673
1674mlx[0-9]*)
1675	unit=${i#mlx}
1676	mkdev mlx$unit c %mlx_chr% $unit
1677	;;
1678
1679mly[0-9]*)
1680	unit=${i#mly}
1681	mkdev mly$unit c %mly_chr% $unit
1682	;;
1683
1684twa[0-9]*)
1685	unit=${i#twa}
1686	mkdev twa$unit c %twa_chr% $unit
1687	;;
1688
1689twe[0-9]*)
1690	unit=${i#twe}
1691	mkdev twe$unit c %twe_chr% $unit
1692	;;
1693
1694icp[0-9]*)
1695	unit=${i#icp}
1696	mkdev icp$unit c %icp_chr% $unit
1697	;;
1698
1699agp[0-9]*)
1700	unit=${i#agp}
1701	mkdev agp$unit c %agp_chr% $unit 644
1702	if [ "$unit" = "0" ]; then
1703		lndev agp$unit agpgart
1704	fi
1705	;;
1706
1707pci[0-9]*)
1708	unit=${i#pci}
1709	mkdev pci$unit c %pci_chr% $unit 640
1710	;;
1711
1712dpti[0-9]*)
1713	unit=${i#dpti}
1714	mkdev dpti$unit c %dpti_chr% $unit
1715	;;
1716
1717dpt[0-9]*)
1718	unit=${i#dpt}
1719	mkdev dpt$unit c %dpt_chr% $unit
1720	;;
1721
1722altq)
1723	makedir altq 755
1724	unit=0
1725	for dev in altq cbq wfq afm fifoq red rio localq hfsc cdnr blue priq jobs
1726	do
1727		mkdev altq/$dev c %altq_chr% $unit 644
1728		unit=$(($unit + 1))
1729	done
1730	;;
1731
1732wsfont)
1733	mkdev wsfont c %wsfont_chr% 0 644
1734	;;
1735
1736cir[0-9]*)
1737	unit=${i#cir}
1738	mkdev cir$unit c %cir_chr% $unit 666
1739	;;
1740
1741irframe[0-9]*)
1742	unit=${i#irframe}
1743	mkdev irframe$unit c %irframe_chr% $unit
1744	;;
1745
1746fcom[0-9]*)
1747	unit=${i#fcom}
1748	mkdev fcom$unit c %fcom_chr% $unit "" "" $u_uucp
1749	;;
1750
1751openfirm)
1752	mkdev openfirm c %openfirm_chr% 0 444
1753	;;
1754
1755pad[0-9]*)
1756	unit=${i#pad}
1757	mkdev pad$unit c %pad_chr% $unit 444
1758	;;
1759
1760qemufwcfg[0-9]*)
1761	unit=${i#qemufwcfg}
1762	mkdev qemufwcfg$unit c %qemufwcfg_chr% $unit 660
1763	;;
1764
1765vio9p[0-9]*)
1766	unit=${i#vio9p}
1767	mkdev vio9p$unit c %vio9p_chr% $unit 660
1768	;;
1769
1770fault)
1771	mkdev fault c %fault_chr% 0
1772	;;
1773
1774nvram)
1775	mkdev nvram c %nvram_chr% 0 644
1776	;;
1777
1778rtc)
1779	mkdev rtc c %rtc_chr% 0 644
1780	;;
1781
1782clockctl)
1783	mkdev clockctl c %clockctl_chr% 0 660 $g_ntpd
1784	;;
1785
1786kttcp)
1787	mkdev kttcp c %kttcp_chr% 0
1788	;;
1789
1790dmoverio)
1791	mkdev dmoverio c %dmoverio_chr% 0 644
1792	;;
1793
1794veriexec)
1795	mkdev veriexec c %veriexec_chr% 0 600
1796	;;
1797
1798vhci[0-7]*)
1799	unit=${i#vhci}
1800	mkdev vhci$unit c %vhci_chr% $unit
1801	;;
1802
1803ttyv[0-9]*)
1804	unit=${i#ttyv}
1805	mkdev ttyv$unit c %pc_chr% $unit
1806	;;
1807
1808# arm, acorn32
1809ttyv[0-9]*)
1810	unit=${i#ttyv}
1811	mkdev ttyv$unit c %physcon_chr% $unit
1812	;;
1813
1814arcpp[0-9]*)
1815	unit=${i#arcpp}
1816	mkdev arcpp$unit c %arcpp_chr% $unit
1817	;;
1818
1819par[0-9]*)
1820	unit=${i#par}
1821	case $unit in
1822	0)
1823		mkdev par$unit c %par_chr% $unit
1824		;;
1825	*)
1826		warn "bad unit for par in: $i"
1827		;;
1828	esac
1829	;;
1830
1831cpi[0-9]*)
1832	unit=${i#cpi}
1833	mkdev cpi$unit c %cpi_chr% $unit
1834	;;
1835
1836ite[0-9]*|ttye[0-9]*)
1837	case $i in
1838	ite*)	unit=${i#ite};;
1839	ttye*)	unit=${i#ttye};;
1840	esac
1841	mkdev ttye$unit c %ite_chr% $unit
1842	;;
1843
1844pms[0-9]*)
1845	unit=${i#pms}
1846	mkdev pms$unit c %opms_chr% $unit
1847	;;
1848
1849qms[0-9]*)
1850	unit=${i#qms}
1851	mkdev qms$unit c %qms_chr% $unit
1852	;;
1853
1854lms[0-9]*)
1855	unit=${i#lms}
1856	mkdev lms$unit c %lms_chr% $unit
1857	;;
1858
1859mms[0-9]*)
1860	unit=${i#mms}
1861	mkdev mms$unit c %mms_chr% $unit
1862	;;
1863
1864mouse-pms[0-9]*|mouse-qms[0-9]*)
1865	case $i in
1866	mouse-pms*) name=pms ;;
1867	mouse-qms*) name=qms ;;
1868	esac
1869	unit=${i#mouse-${name}}
1870	lndev $name$unit mouse
1871	;;
1872
1873kbd)
1874	mkdev kbd c %kbd_chr% 0
1875	;;
1876
1877kbdctl)
1878	mkdev kbdctl c %kbd_chr% 1
1879	;;
1880
1881vidcconsole0)
1882	mkdev vidcconsole0 c %vidcconsole_chr% 0 640
1883	;;
1884
1885view[0-9]*)
1886	unit=${i#view}
1887	mkdev view$unit c %view_chr% $unit 666
1888	;;
1889
1890mouse[0-9]*)
1891	unit=${i#mouse}
1892	case $unit in
1893	0|1)
1894		mkdev mouse$unit c %ms_chr% $unit 666
1895		if [ $unit = 0 ]; then
1896			lndev mouse$unit mouse
1897		fi
1898		;;
1899	*)
1900		warn "bad unit for mouse in: $i"
1901		;;
1902	esac
1903	;;
1904
1905panel)
1906	mkdev panel0 c %panel_chr% 0 660
1907	;;
1908
1909tslcd)
1910	mkdev tslcd0 c %tslcd_chr% 0 660
1911	;;
1912
1913ipty)
1914	mkdev ttyp0 c %pts_chr% 0 666
1915	mkdev ttyp1 c %pts_chr% 1 666
1916	mkdev ptyp0 c %ptc_chr% 0 666
1917	mkdev ptyp1 c %ptc_chr% 1 666
1918	;;
1919
1920ptm)
1921	makedir pts 755
1922	mkdev ptmx c %ptm_chr% 0 666
1923	mkdev ptm c %ptm_chr% 1 666
1924	;;
1925
1926grf[0-9]*)
1927	unit=${i#grf}
1928	mkdev grf$unit c %grf_chr% $unit 666
1929	;;
1930
1931etvme)
1932	mkdev etvme c %et_chr% 0
1933	;;
1934
1935leo[0-9]*)
1936	unit=${i#leo}
1937	mkdev leo$unit c %leo_chr% $unit
1938	;;
1939
1940scif[0-9]*)
1941	unit=${i#scif}
1942	mkdev scif$unit c %scif_chr% $(($unit + $dialin )) "" "" $u_uucp
1943	mkdev dscif$unit c %scif_chr% $(($unit + $dialout)) "" "" $u_uucp
1944	;;
1945
1946sci[0-9]*)
1947	unit=${i#sci}
1948	mkdev sci$unit c %sci_chr% $(($unit + $dialin )) "" "" $u_uucp
1949	mkdev dsci$unit c %sci_chr% $(($unit + $dialout)) "" "" $u_uucp
1950	;;
1951
1952maple[ABCD]|maple[ABCD][0-9]*)
1953	case $i in
1954	mapleA*) name="mapleA"; unit=0;;
1955	mapleB*) name="mapleB"; unit=1;;
1956	mapleC*) name="mapleC"; unit=2;;
1957	mapleD*) name="mapleD"; unit=3;;
1958	esac
1959	subunit=${i#$name}
1960	mkdev $name$subunit c %maple_chr% $(($unit * 8 + 0$subunit))
1961	;;
1962
1963mmem[0-9]*)
1964	unit=${i#mmem}
1965	for pt in 0	# 1 2 3 4 ... 255
1966	do
1967#		mkdev mmem${unit}.${pt}a  b %mmem_blk% $(($unit * 4096 + $pt * 16 + 0)) 640 $g_operator
1968		mkdev mmem${unit}.${pt}c  b %mmem_blk% $(($unit * 4096 + $pt * 16 + 2)) 640 $g_operator
1969#		mkdev rmmem${unit}.${pt}a c %mmem_chr% $(($unit * 4096 + $pt * 16 + 0)) 640 $g_operator
1970		mkdev rmmem${unit}.${pt}c c %mmem_chr% $(($unit * 4096 + $pt * 16 + 2)) 640 $g_operator
1971	done
1972	;;
1973
1974mlcd[0-9]*)
1975	unit=${i#mlcd}
1976	for pt in 0	# 1 2 3 4 ... 255
1977	do
1978		mkdev mlcd${unit}.${pt} c %mlcd_chr% $(($unit * 256 + $pt)) 640 $g_operator
1979	done
1980	;;
1981
1982ixpcom[0-9]*)
1983	unit=${i#ixpcom}
1984	mkdev ixpcom$unit c %ixpcom_chr% $unit "" "" $u_uucp
1985	;;
1986
1987epcom[0-9]*)
1988	unit=${i#epcom}
1989	mkdev epcom$unit c %epcom_chr% $unit "" "" $u_uucp
1990	;;
1991
1992plcom[0-9]*)
1993	unit=${i#plcom}
1994	mkdev plcom$unit c %plcom_chr% $unit "" "" $u_uucp
1995	mkdev dplcom$unit c %plcom_chr% $(($unit + $dialout)) "" "" $u_uucp
1996	;;
1997
1998wmcom[0-9]*)
1999	unit=${i#wmcom}
2000	mkdev wmcom$unit c %wmcom_chr% $unit "" "" $u_uucp
2001	;;
2002
2003ucbsnd)
2004	mkdev ucbsnd c %ucbsnd_chr% 0 666
2005	;;
2006
2007adb)
2008	mkdev adb c %aed_chr% 0 666
2009	;;
2010
2011asc[0-9]*)
2012	unit=${i#asc}
2013	mkdev asc$unit c %asc_chr% $unit 666
2014	;;
2015
2016bwtwo[0-9]*)
2017	unit=${i#bwtwo}
2018	mkdev bwtwo$unit c %bwtwo_chr% $unit 666
2019	;;
2020
2021cgtwo[0-9]*)
2022	unit=${i#cgtwo}
2023	mkdev cgtwo$unit c %cgtwo_chr% $unit 666
2024	;;
2025
2026cgthree[0-9]*)
2027	unit=${i#cgthree}
2028	mkdev cgthree$unit c %cgthree_chr% $unit 666
2029	;;
2030
2031cgfour[0-9]*)
2032	unit=${i#cgfour}
2033	mkdev cgfour$unit c %cgfour_chr% $unit 666
2034	;;
2035
2036cgsix[0-9]*)
2037	unit=${i#cgsix}
2038	mkdev cgsix$unit c %cgsix_chr% $unit 666
2039	;;
2040
2041cgeight[0-9]*)
2042	unit=${i#cgeight}
2043	mkdev cgeight$unit c %cgeight_chr% $unit 666
2044	;;
2045
2046tcx[0-9]*)
2047	unit=${i#tcx}
2048	mkdev tcx$unit c %tcx_chr% $unit 666
2049	;;
2050
2051xd[0-9]*|xy[0-9]*)
2052	case $i in
2053	xd*)	name=xd; unit=${i#xd}; blk=%xd_blk%;	chr=%xd_chr%;;
2054	xy*)	name=xy; unit=${i#xy}; blk=%xy_blk%;	chr=%xy_chr%;;
2055	esac
2056	%MKDISK% $name $unit $blk $chr
2057	;;
2058
2059magma[0-9]*)
2060	unit=${i#magma}
2061	if [ 0$unit -gt 3 ]; then
2062		warn "bad unit for $i: $unit"
2063		break
2064	fi
2065	for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f
2066	do
2067		case $j in
2068		[0-9])	jn=$j ;;
2069		a)	jn=10 ;;
2070		b)	jn=11 ;;
2071		c)	jn=12 ;;
2072		d)	jn=13 ;;
2073		e)	jn=14 ;;
2074		f)	jn=15 ;;
2075		esac
2076		mkdev tty$unit$j c %mtty_chr% $(($unit * 64 + $jn))
2077	done
2078	mkdev bpp${unit}0 c %mbpp_chr% $(($unit * 64 + 0))
2079	mkdev bpp${unit}1 c %mbpp_chr% $(($unit * 64 + 1))
2080	;;
2081
2082clcd[0-9]*)
2083	unit=${i#clcd}
2084	if [ 0$unit -gt 7 ]; then
2085		warn "bad unit for $i: $unit"
2086		break
2087	fi
2088	for j in 0 1 2 3 4 5 6 7
2089	do
2090		mkdev ttyA$unit$j c %clcd_chr% $(($unit * 8 + $j + $dialin)) "" "" $u_uucp
2091		mkdev dtyA$unit$j c %clcd_chr% $(($unit * 8 + $j + $dialout)) "" "" $u_uucp
2092	done
2093	;;
2094
2095spif[0-9]*)
2096	unit=${i#spif}
2097	if [ 0$unit -gt 3 ]; then
2098		warn "bad unit for $i: $unit"
2099		break
2100	fi
2101	for j in 0 1 2 3 4 5 6 7; do
2102		mkdev ttyS$unit$j c %stty_chr% $(($unit * 64 + $j)) "" "" $u_uucp
2103	done
2104	mkdev bppS${unit}0 c %sbpp_chr% $(($unit * 64 + 0))
2105	mkdev bppS${unit}1 c %sbpp_chr% $(($unit * 64 + 1))
2106	;;
2107
2108bpp|bpp[0-9]*)
2109	unit=${i#bpp}
2110	mkdev bpp$unit c %bpp_chr% $(($unit + 0))
2111	;;
2112
2113tctrl[0-9]*)
2114	unit=${i#tctrl}
2115	mkdev tctrl$unit c %tctrl_chr% $unit 666
2116	;;
2117
2118bmd[0-9]*)
2119	unit=${i#bmd}
2120	mkdev bmd${unit}a  b %bmd_blk% $(($unit * 8 + 0)) 640 $g_operator
2121	mkdev bmd${unit}c  b %bmd_blk% $(($unit * 8 + 2)) 640 $g_operator
2122	mkdev rbmd${unit}a c %bmd_chr% $(($unit * 8 + 0)) 640 $g_operator
2123	mkdev rbmd${unit}c c %bmd_chr% $(($unit * 8 + 2)) 640 $g_operator
2124	;;
2125
2126sram)
2127	mkdev sram c %sram_chr% 0 644
2128	;;
2129
2130ttyS[0-9]*)
2131	unit=${i#ttyS}
2132	mkdev ttyS$unit c %sacom_chr% $(($unit + $dialin )) "" "" $u_uucp
2133	mkdev dtyS$unit c %sacom_chr% $(($unit + $dialout)) "" "" $u_uucp
2134	;;
2135
2136atabus[0-9]*)
2137	unit=${i#atabus}
2138	mkdev atabus$unit c %atabus_chr% $unit 644
2139	;;
2140
2141drm[0-9]*)
2142	unit=${i#drm}
2143	unit2=$((unit + 128))
2144	makedir dri 755
2145	mkdev dri/card$unit c %drm_chr% $unit 660
2146	mkdev dri/renderD${unit2} c %drm_chr% ${unit2} 660
2147	;;
2148
2149drvctl)
2150	mkdev drvctl c %drvctl_chr% 0 644
2151	;;
2152
2153isv)
2154	mkdev isv c %isv_chr% 0 644
2155	;;
2156
2157tap|tap[0-9]*)
2158	unit=${i#tap}
2159	case "$unit" in
2160	[0-9]*)
2161		mkdev tap${unit} c %tap_chr% ${unit} 600
2162		;;
2163	"")
2164		mkdev tap c %tap_chr% 0xfffff 600
2165		;;
2166	esac
2167	;;
2168
2169srt[0-9]*)
2170	unit=${i#srt}
2171	mkdev srt$unit c %srt_chr% $unit 600
2172	;;
2173
2174tpm)
2175	mkdev tpm c %tpm_chr% 0 600
2176	;;
2177
2178dtrace)
2179	makedir dtrace 755
2180	mkdev dtrace/dtrace c %dtrace_chr% 0 600
2181	;;
2182
2183fw[0-9]*)
2184	unit=${i#fw}
2185	for j in 0 1 2 3
2186	do
2187		mkdev fw${unit}.${j} c %fw_chr% $((${unit} * 256 + ${j})) 660 ${g_operator}
2188		mkdev fwmem${unit}.${j} c %fw_chr% $((65536 + ${unit} * 256 + ${j})) 660 ${g_operator}
2189	done
2190	;;
2191
2192# create putter device and symlinks for all subsystems using it
2193putter)
2194	mkdev putter c %putter_chr% 0 600
2195	mkdev pud c %putter_chr% 1 600
2196	lndev putter puffs
2197	;;
2198
2199zfs)
2200	mkdev zfs c %zfs_chr% 0 600
2201	makedir zpool 755
2202	;;
2203
2204iscsi[0-9]*)
2205	unit=${i#iscsi}
2206	mkdev iscsi${unit} c %iscsi_chr% $unit 600
2207	;;
2208
2209vchiq)
2210	mkdev vchiq c %vchiq_chr% 0 600
2211	;;
2212
2213nvme[0-9]*ns[0-9]*)
2214	unit=${i#nvme}
2215	unit=${unit%ns*}
2216	subunit=${i#nvme${unit}ns}
2217	if [ 0$subunit -le 0 ] || [ 0$subunit -ge 65536 ]; then
2218		warn "bad nsid for $i: $subunit"
2219		break
2220	fi
2221	mkdev nvme${unit}ns$subunit c %nvme_chr% $(($unit * 65536 + $subunit))
2222	;;
2223
2224nvme[0-9]*)
2225	unit=${i#nvme}
2226	mkdev nvme$unit c %nvme_chr% $(($unit * 65536))
2227	;;
2228
2229nvmm)
2230	mkdev nvmm c %nvmm_chr% 0 660 $g_nvmm
2231	;;
2232
2233autofs)
2234	mkdev autofs c %autofs_chr% 0 600
2235	;;
2236
2237kcov)
2238        mkdev kcov c %kcov_chr% 0
2239        ;;
2240
2241ipmi[0-9]*)
2242	unit=${i#ipmi}
2243	mkdev ipmi${unit} c %ipmi_chr% $unit 600
2244	;;
2245
2246xmm[0-9])
2247	unit=${i#xmm}
2248	makedir xmm${unit} 755
2249	mkdev xmm${unit}/rpc c %wwanc_chr% $(($unit * 65536 + 1))
2250	mkdev ttyXMM${unit}0 c %wwanc_chr% $(($unit * 65536 + 2))
2251	mkdev ttyXMM${unit}1 c %wwanc_chr% $(($unit * 65536 + 4))
2252	;;
2253
2254acpi)
2255	mkdev acpi c %acpi_chr% 0
2256	;;
2257
2258smbios)
2259	mkdev smbios c %smbios_chr% 0
2260	;;
2261
2262efi)
2263	mkdev efi c %efi_chr% 0 660
2264	;;
2265
2266sht3xtemp[0-9]*)
2267	unit=${i#sht3xtemp}
2268	mkdev sht3xtemp$unit c %sht3xtemp_chr% $unit 664
2269	;;
2270
2271scmd[0-9]*)
2272	unit=${i#scmd}
2273	mkdev scmd$unit c %scmd_chr% $unit 666
2274	;;
2275
2276ttyVI[0-9][0-9])
2277	port=${i#ttyVI?}
2278	devunit=${i%$port}
2279	unit=${devunit#ttyVI}
2280	mkdev ttyVI$unit$port c %viocon_chr% $((16*$unit + $port))
2281	;;
2282
2283ttyVI)
2284	makedev ttyVI00 ttyVI10 ttyVI20 ttyVI30
2285	;;
2286
2287midevend)
2288%MI_DEVICES_END%
2289local)
2290	if [ -f "$0.local" ]; then
2291		umask 0
2292		if [ -n "$count_nodes" ]; then
2293			count_nodes=$((count_nodes + \
2294			    $(linecount "$("$HOST_SH" "$0.local" $opts -s all)") ))
2295		else
2296			"$HOST_SH" "$0.local" $opts all
2297		fi
2298		umask 077
2299	fi
2300	;;
2301
2302*)
2303	warn "$i: unknown device"
2304	;;
2305
2306esac
2307done
2308
2309}
2310
2311
2312# three variants of disk partitions - max 8, max 16, max 16 with highpartoffset
2313# hack; only the one used by port is retained in final MAKEDEV script
2314# routine is called as:
2315# makedisk name unit blk chr
2316makedisk_p8()
2317{
2318	name="$1"; unit="$2"; blk="$3"; chr="$4"
2319
2320	ro=%RAWDISK_OFF%
2321	mkdev ${name}${unit}	b $blk $(($unit * 8 + $ro))	640 $g_operator
2322	mkdev r${name}${unit}	c $chr $(($unit * 8 + $ro))	640 $g_operator
2323
2324	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2325	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2326	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2327	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2328	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2329	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2330	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2331	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2332	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2333	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2334	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2335	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2336	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2337	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2338	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2339	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2340}
2341
2342makedisk_p12high()
2343{
2344	ho=524280	# offset for partition 9 to 11 (same as ...p16high)
2345	name="$1"; unit="$2"; blk="$3"; chr="$4"
2346
2347	ro=%RAWDISK_OFF%
2348	mkdev ${name}${unit}	b $blk $(($unit * 8 + $ro))	640 $g_operator
2349	mkdev r${name}${unit}	c $chr $(($unit * 8 + $ro))	640 $g_operator
2350
2351	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2352	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2353	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2354	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2355	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2356	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2357	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2358	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2359	mkdev ${name}${unit}i	b $blk $(($unit * 8 + $ho + 8)) 640 $g_operator
2360	mkdev ${name}${unit}j	b $blk $(($unit * 8 + $ho + 9)) 640 $g_operator
2361	mkdev ${name}${unit}k	b $blk $(($unit * 8 + $ho + 10)) 640 $g_operator
2362	mkdev ${name}${unit}l	b $blk $(($unit * 8 + $ho + 11)) 640 $g_operator
2363	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2364	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2365	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2366	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2367	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2368	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2369	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2370	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2371	mkdev r${name}${unit}i	c $chr $(($unit * 8 + $ho + 8)) 640 $g_operator
2372	mkdev r${name}${unit}j	c $chr $(($unit * 8 + $ho + 9)) 640 $g_operator
2373	mkdev r${name}${unit}k	c $chr $(($unit * 8 + $ho + 10)) 640 $g_operator
2374	mkdev r${name}${unit}l	c $chr $(($unit * 8 + $ho + 11)) 640 $g_operator
2375}
2376
2377makedisk_p16()
2378{
2379	name="$1"; unit="$2"; blk="$3"; chr="$4"
2380
2381	ro=%RAWDISK_OFF%
2382	mkdev ${name}${unit}	b $blk $(($unit * 16 + $ro))	640 $g_operator
2383	mkdev r${name}${unit}	c $chr $(($unit * 16 + $ro))	640 $g_operator
2384
2385	mkdev ${name}${unit}a	b $blk $(($unit * 16 + 0))	640 $g_operator
2386	mkdev ${name}${unit}b	b $blk $(($unit * 16 + 1))	640 $g_operator
2387	mkdev ${name}${unit}c	b $blk $(($unit * 16 + 2))	640 $g_operator
2388	mkdev ${name}${unit}d	b $blk $(($unit * 16 + 3))	640 $g_operator
2389	mkdev ${name}${unit}e	b $blk $(($unit * 16 + 4))	640 $g_operator
2390	mkdev ${name}${unit}f	b $blk $(($unit * 16 + 5))	640 $g_operator
2391	mkdev ${name}${unit}g	b $blk $(($unit * 16 + 6))	640 $g_operator
2392	mkdev ${name}${unit}h	b $blk $(($unit * 16 + 7))	640 $g_operator
2393	mkdev ${name}${unit}i	b $blk $(($unit * 16 + 8))	640 $g_operator
2394	mkdev ${name}${unit}j	b $blk $(($unit * 16 + 9))	640 $g_operator
2395	mkdev ${name}${unit}k	b $blk $(($unit * 16 + 10))	640 $g_operator
2396	mkdev ${name}${unit}l	b $blk $(($unit * 16 + 11))	640 $g_operator
2397	mkdev ${name}${unit}m	b $blk $(($unit * 16 + 12))	640 $g_operator
2398	mkdev ${name}${unit}n	b $blk $(($unit * 16 + 13))	640 $g_operator
2399	mkdev ${name}${unit}o	b $blk $(($unit * 16 + 14))	640 $g_operator
2400	mkdev ${name}${unit}p	b $blk $(($unit * 16 + 15))	640 $g_operator
2401	mkdev r${name}${unit}a	c $chr $(($unit * 16 + 0))	640 $g_operator
2402	mkdev r${name}${unit}b	c $chr $(($unit * 16 + 1))	640 $g_operator
2403	mkdev r${name}${unit}c	c $chr $(($unit * 16 + 2))	640 $g_operator
2404	mkdev r${name}${unit}d	c $chr $(($unit * 16 + 3))	640 $g_operator
2405	mkdev r${name}${unit}e	c $chr $(($unit * 16 + 4))	640 $g_operator
2406	mkdev r${name}${unit}f	c $chr $(($unit * 16 + 5))	640 $g_operator
2407	mkdev r${name}${unit}g	c $chr $(($unit * 16 + 6))	640 $g_operator
2408	mkdev r${name}${unit}h	c $chr $(($unit * 16 + 7))	640 $g_operator
2409	mkdev r${name}${unit}i	c $chr $(($unit * 16 + 8))	640 $g_operator
2410	mkdev r${name}${unit}j	c $chr $(($unit * 16 + 9))	640 $g_operator
2411	mkdev r${name}${unit}k	c $chr $(($unit * 16 + 10))	640 $g_operator
2412	mkdev r${name}${unit}l	c $chr $(($unit * 16 + 11))	640 $g_operator
2413	mkdev r${name}${unit}m	c $chr $(($unit * 16 + 12))	640 $g_operator
2414	mkdev r${name}${unit}n	c $chr $(($unit * 16 + 13))	640 $g_operator
2415	mkdev r${name}${unit}o	c $chr $(($unit * 16 + 14))	640 $g_operator
2416	mkdev r${name}${unit}p	c $chr $(($unit * 16 + 15))	640 $g_operator
2417}
2418
2419makedisk_p16high()
2420{
2421	ho=524280	# offset for partition 9 to 16
2422	name="$1"; unit="$2"; blk="$3"; chr="$4"
2423
2424	ro=%RAWDISK_OFF%
2425	mkdev ${name}${unit}	b $blk $(($unit * 8 + $ro))	640 $g_operator
2426	mkdev r${name}${unit}	c $chr $(($unit * 8 + $ro))	640 $g_operator
2427
2428	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2429	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2430	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2431	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2432	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2433	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2434	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2435	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2436	mkdev ${name}${unit}i	b $blk $(($unit * 8 + $ho + 8)) 640 $g_operator
2437	mkdev ${name}${unit}j	b $blk $(($unit * 8 + $ho + 9)) 640 $g_operator
2438	mkdev ${name}${unit}k	b $blk $(($unit * 8 + $ho + 10)) 640 $g_operator
2439	mkdev ${name}${unit}l	b $blk $(($unit * 8 + $ho + 11)) 640 $g_operator
2440	mkdev ${name}${unit}m	b $blk $(($unit * 8 + $ho + 12)) 640 $g_operator
2441	mkdev ${name}${unit}n	b $blk $(($unit * 8 + $ho + 13)) 640 $g_operator
2442	mkdev ${name}${unit}o	b $blk $(($unit * 8 + $ho + 14)) 640 $g_operator
2443	mkdev ${name}${unit}p	b $blk $(($unit * 8 + $ho + 15)) 640 $g_operator
2444	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2445	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2446	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2447	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2448	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2449	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2450	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2451	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2452	mkdev r${name}${unit}i	c $chr $(($unit * 8 + $ho + 8)) 640 $g_operator
2453	mkdev r${name}${unit}j	c $chr $(($unit * 8 + $ho + 9)) 640 $g_operator
2454	mkdev r${name}${unit}k	c $chr $(($unit * 8 + $ho + 10)) 640 $g_operator
2455	mkdev r${name}${unit}l	c $chr $(($unit * 8 + $ho + 11)) 640 $g_operator
2456	mkdev r${name}${unit}m	c $chr $(($unit * 8 + $ho + 12)) 640 $g_operator
2457	mkdev r${name}${unit}n	c $chr $(($unit * 8 + $ho + 13)) 640 $g_operator
2458	mkdev r${name}${unit}o	c $chr $(($unit * 8 + $ho + 14)) 640 $g_operator
2459	mkdev r${name}${unit}p	c $chr $(($unit * 8 + $ho + 15)) 640 $g_operator
2460}
2461
2462# make only the very few basic disk device nodes - 'a' partition
2463# and raw partition
2464makedisk_minimal()
2465{
2466	name=$1; unit=$2; blk=$3; chr=$4
2467	doff=%DISKMINOROFFSET%
2468	ro=%RAWDISK_OFF%
2469	rn=%RAWDISK_NAME%
2470
2471	mkdev ${name}${unit}	b $blk $(($unit * $doff + $ro))	640 $g_operator
2472	mkdev r${name}${unit}	c $chr $(($unit * $doff + $ro))	640 $g_operator
2473
2474	mkdev ${name}${unit}a	b $blk $(($unit * $doff + 0))	640 $g_operator
2475	mkdev ${name}${unit}$rn b $blk $(($unit * $doff + $ro)) 640 $g_operator
2476	mkdev r${name}${unit}a	c $chr $(($unit * $doff + 0))	640 $g_operator
2477	mkdev r${name}${unit}$rn c $chr $(($unit * $doff + $ro)) 640 $g_operator
2478}
2479
2480# create_mfs_dev nodes
2481#	Create a memory file system for a given number of device nodes,
2482#	and mount it.  Attempts to use mount_tmpfs, or falls back to
2483#	mount_mfs.
2484#
2485#	If do_redirect, then also redirect output to the console.
2486#
2487create_mfs_dev()
2488{
2489	ndevnodes=${1-1200}
2490	dev_mountpoint=${PWD:-/dev}
2491
2492	# Number of inodes is the specified number of device nodes, plus
2493	# a margin to allow for extra device nodes created later.
2494	ninode=$((ndevnodes * 11 / 10))
2495	# Add 2 reserved inodes (needed for both mfs and tmpfs), and round
2496	# up to a multiple of 32 (needed for mfs, not needed for tmpfs).
2497	ninode=$(( (ninode + 2 + 31) / 32 * 32 ))
2498	# Try tmpfs; if that fails try mfs.
2499	#
2500	# For tmpfs, allocate 16KB and 512 byte per node.
2501	# Actual requirements are much lower, but the size limit
2502	# is only intended to avoid accidental writing to /dev.
2503	fs_bytes=$((16384 + ninode * 512))
2504	if mount_tmpfs -s $fs_bytes -n $ninode -m 0755 \
2505		-o union tmpfs "$dev_mountpoint"
2506	then
2507		fstype=tmpfs
2508	else
2509		# This file system size calculation is exact for mount_mfs(8)
2510		# with 512-byte sectors.  40960 bytes (80 blocks) is the
2511		# minimum size allowed by mount_mfs.
2512		fs_bytes=$((8192 + 2 * 8192 + 4096 + ninode*512 + 8192))
2513		[ "$fs_bytes" -lt 40960 ] && fs_bytes=40960
2514		fs_blocks=$((fs_bytes/512))
2515		if mount_mfs -b 4096 -f 512 -s $fs_blocks -n $ninode -p 0755 \
2516		    -o union swap "$dev_mountpoint"
2517		then
2518			fstype=mfs
2519		else
2520			die "Failed to create memory file system"
2521		fi
2522	fi
2523
2524	# Our current directory was in the lower file system; change it to
2525	# the newly mounted upper file system.
2526	cd "$dev_mountpoint"
2527
2528	if $do_redirect; then
2529		# Redirect stdout and stderr to console
2530		${MKNOD} -m 600 -g 0 -u 0 temp_console c %CONSOLE_CMAJOR% 0
2531		exec >temp_console 2>&1
2532		rm temp_console
2533	fi
2534
2535	echo "Created $fstype $dev_mountpoint" \
2536		"($fs_bytes byte, $ninode inodes)"
2537}
2538
2539#
2540# MAIN: If MAKEDEV_AS_LIBRARY is set, then we are being used as a
2541# function library, so just return.  Otherwise, do all the real work.
2542#
2543[ -n "${MAKEDEV_AS_LIBRARY}" ] && return
2544makedev_main makedev ${1+"$@"}
2545