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