MAKEDEV.tmpl revision 1.168
1#!/bin/sh -
2#	$NetBSD: MAKEDEV.tmpl,v 1.168 2013/05/01 13:12:00 kiyohara 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_kmem="%gid_kmem%"
500	g_ntpd="%gid_ntpd%"
501	g_operator="%gid_operator%"
502	g_wheel="%gid_wheel%"
503	dialin=0
504	dialout=524288
505	callunit=262144
506
507	# only allow read&write for owner by default
508	umask 077
509
510	# Set fdesc_mounted=true if the fdesc file system is mounted
511	# on the current directory (typically "/dev").
512	# Later, this will be used to suppress creation of device nodes
513	# that are supplied by the fdesc file system.
514	#
515	fdesc_mounted=false
516	if [ -d fd ]; then
517		# Parse the output from "mount -u -o nosuchoption .".
518		# We don't parse the output from df(1) because that's
519		# less likely to be available on install media.
520		#
521		# If the current directory is a mount point for the
522		# fdesc file system, then the expected output (whether
523		# or not the current user is root) is:
524		#	mount_fdesc: -o suchoption: option not supported.
525		#
526		# If the current directory is not a mount point, then
527		# the expected output is:
528		#	mount: .: unknown special file or file system.
529		#
530		# If we are not running on NetBSD, or mount(8) is not
531		# found, then we should get some other error message.
532		#
533		case "$({ LC_ALL=C mount -u -o nosuchoption . ; } 2>&1)" in
534		*mount_fdesc*)	fdesc_mounted=true ;;
535		esac
536	fi
537
538	# do_force requires mknod
539	if $do_force; then
540		if $do_mtree || $do_pax || $do_specfile; then
541			die "-f option works only with mknod"
542		fi
543		do_mknod=true
544	fi
545
546	# do_force and do_update do not work together
547	if $do_force && $do_update; then
548		die "-f and -u options do not work together"
549	fi
550
551	# If no explicit method was specified on the command line or
552	# forced above, then use one of mtree, pax, or mknod, in that
553	# order of preference.
554	#
555	# mtree is preferred because it's fast and designed for the
556	# purpose.  However, it's unlikely to be available early in the
557	# boot sequence, when init(8) may invoke MAKEDEV(8).
558	#
559	# pax is usually acceptable, and it's likely to be available
560	# early in the boot sequence.  However, it's much slower than mtree.
561	#
562	# mknod is just very slow, because the shell has to fork for
563	# each device node.
564	#
565	if ! ( $do_mtree || $do_pax || $do_mknod || $do_specfile ); then
566		if check_mtree "${TOOL_MTREE}"; then
567			do_mtree=true
568		elif check_pax "${TOOL_PAX}"; then
569			do_pax=true
570		else
571			do_mknod=true
572		fi
573	fi
574
575	# Now we need exactly one node-creation method.
576	case $(( $($do_mtree && echo 1 || echo 0) + \
577		$($do_pax && echo 1 || echo 0) + \
578		$($do_mknod && echo 1 || echo 0) + \
579		$($do_specfile && echo 1 || echo 0) ))
580	in
581	1)	: OK ;;
582	*)	die "-m, -p, -s, and -t options are mutually exclusive" ;;
583	esac
584
585	# If we are using mknod, then decide what options to pass it.
586	if $do_mknod; then
587		MKNOD="${TOOL_MKNOD:-mknod} -F netbsd"
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 ccd0 ccd1 ccd2 ccd3
817	makedev cgd0 cgd1 cgd2 cgd3
818	makedev fss0 fss1 fss2 fss3
819	makedev md0 md1
820	makedev raid0 raid1 raid2 raid3 raid4 raid5 raid6 raid7
821	makedev vnd0 vnd1 vnd2 vnd3
822	makedev iscsi0
823	makedev bpf npf
824	makedev tun0 tun1 tun2 tun3
825	makedev ipl pf crypto random
826	makedev lockstat clockctl cpuctl
827	makedev atabus0 atabus1 atabus2 atabus3 atabus4 atabus5 atabus6 atabus7
828	makedev tap tap0 tap1 tap2 tap3
829	makedev gpio gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
830	makedev pad pad0 pad1 pad2 pad3
831	makedev bthub
832	makedev putter
833	makedev drvctl
834	makedev video
835	makedev dtv
836	makedev drm0
837	makedev altmem
838	makedev zfs
839	makedev local # do this last
840	;;
841
842init)
843	# unless overridden by MD entry, this is equal to 'all'
844	makedev all opty
845	;;
846
847%MI_DEVICES_BEGIN%
848audio)
849	makedev audio0 audio1 audio2 audio3
850	makedev hdaudio0 hdaudio1 hdaudio2 hdaudio3
851	lndev sound0 sound
852	lndev audio0 audio
853	lndev mixer0 mixer
854	lndev audioctl0 audioctl
855	;;
856
857gpio)
858	makedev gpio0 gpio1 gpio2 gpio3 gpio4 gpio5 gpio6 gpio7
859	lndev gpio0 gpio
860	;;
861
862pad)
863	makedev pad0 pad1 pad2 pad3
864	lndev pad0 pad
865	;;
866
867radio)
868	makedev radio0 radio1
869	lndev radio0 radio
870	;;
871
872video)
873	makedev video0 video1 video2 video3
874	;;
875
876dtv)
877	makedev dtv0 dtv1 dtv2 dtv3
878	;;
879
880iic)
881	makedev iic0 iic1 iic2 iic3
882	;;
883
884altmem)
885	makedev altmem0 altmem1
886	;;
887
888ramdisk)
889	makedev floppy md0
890	;;
891
892usbs)
893	makedev usb usb0 usb1 usb2 usb3 usb4 usb5 usb6 usb7
894	makedev uhid0 uhid1 uhid2 uhid3
895	makedev ulpt0 ulpt1
896	makedev ttyU0 ttyU1
897	makedev ttyY0 ttyY1
898	makedev ttyHS0
899	makedev urio0
900	makedev uscanner0 uscanner1
901	makedev utoppy0 utoppy1
902	makedev ugen0 ugen1 ugen2 ugen3
903	;;
904
905isdns)
906	makedev isdn isdnctl isdnbchan0 isdnbchan1 isdntel0 isdntel1 isdnteld0 isdnteld1 isdntrc0 isdntrc1
907	;;
908
909std)
910	mkdev		console c %cons_chr% 0	600
911	mkdev		constty c %cons_chr% 1	600
912	mkdev		drum	c %swap_chr% 0	640 $g_kmem
913	mkdev		kmem	c %mem_chr% 1	640 $g_kmem
914	mkdev		mem	c %mem_chr% 0	640 $g_kmem
915	mkdev		null	c %mem_chr% 2	666
916	mkdev		zero	c %mem_chr% 12	666
917	mkdev		klog	c %log_chr% 0	600
918	mkdev		ksyms	c %ksyms_chr% 0 444
919	if ! $fdesc_mounted; then
920		mkdev	tty	c %ctty_chr% 0		666
921		mkdev	stdin	c %filedesc_chr% 0	666
922		mkdev	stdout	c %filedesc_chr% 1	666
923		mkdev	stderr	c %filedesc_chr% 2	666
924	fi
925	;;
926
927usb)
928	mkdev usb c %usb_chr% 255 444
929	;;
930
931usb[0-9]*)
932	unit=${i#usb}
933	usb=usb$unit
934	mkdev usb$unit c %usb_chr% $unit
935	;;
936
937uhid[0-9]*)
938	unit=${i#uhid}
939	mkdev uhid$unit c %uhid_chr% $unit 666
940	;;
941
942ulpt[0-9]*)
943	unit=${i#ulpt}
944	mkdev ulpt$unit c %ulpt_chr% $unit
945	mkdev ulpn$unit c %ulpt_chr% $(($unit + 64))
946	;;
947
948urio[0-9]*)
949	unit=${i#urio}
950	mkdev urio$unit c %urio_chr% $unit 666
951	;;
952
953uscanner[0-9]*)
954	unit=${i#uscanner}
955	mkdev uscanner$unit c %uscanner_chr% $unit
956	;;
957
958utoppy[0-9]*)
959	unit=${i#utoppy}
960	mkdev utoppy$unit c %utoppy_chr% $unit
961	;;
962
963ttyHS[0-9]*)
964	unit=${i#ttyHS}
965	for j in 00 01 02 03 04 05 06 07 08 09 10
966	do
967		base=$(($unit * 16 + ${j#0}))
968		mkdev ttyHS$unit.$j c %uhso_chr% $(($base + $dialin  )) "" "" $u_uucp
969		mkdev dtyHS$unit.$j c %uhso_chr% $(($base + $dialout )) "" "" $u_uucp
970		mkdev ctyHS$unit.$j c %uhso_chr% $(($base + $callunit)) "" "" $u_uucp
971	done
972	;;
973
974ttyY[0-9]*)
975	unit=${i#ttyY}
976	mkdev ttyY$unit c %ucycom_chr% $(($unit + $dialin  )) "" "" $u_uucp
977	mkdev dtyY$unit c %ucycom_chr% $(($unit + $dialout )) "" "" $u_uucp
978	mkdev ctyY$unit c %ucycom_chr% $(($unit + $callunit)) "" "" $u_uucp
979	;;
980
981ttyU[0-9]*)
982	unit=${i#ttyU}
983	mkdev ttyU$unit c %ucom_chr% $(($unit + $dialin	 )) "" "" $u_uucp
984	mkdev dtyU$unit c %ucom_chr% $(($unit + $dialout )) "" "" $u_uucp
985	mkdev ctyU$unit c %ucom_chr% $(($unit + $callunit)) "" "" $u_uucp
986	;;
987
988ugen[0-9]*)
989	unit=${i#ugen}
990	for j in 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
991	do
992		mkdev ugen$unit.$j c %ugen_chr% $(($unit * 16 + ${j#0}))
993	done
994	;;
995
996wscons)
997	makedev ttyE0 ttyE1 ttyE2 ttyE3 ttyE4 ttyE5 ttyE6 ttyE7
998	makedev wsmouse0 wsmouse1 wsmouse2 wsmouse3
999	makedev wskbd0 wskbd1 wskbd2 wskbd3
1000	makedev wsmux0 wsmux1 wsmux2 wsmux3
1001	makedev wsmouse wskbd
1002	makedev ttyEcfg ttyEstat
1003	makedev wsfont
1004	;;
1005
1006wsmouse)
1007	mkdev wsmouse c %wsmux_chr% 0
1008	;;
1009
1010wskbd)
1011	mkdev wskbd c %wsmux_chr% 1
1012	;;
1013
1014wsmux[0-9]*)
1015	unit=${i#wsmux}
1016	mkdev wsmux$unit    c %wsmux_chr% $unit
1017	mkdev wsmuxctl$unit c %wsmux_chr% $(($unit + 128)) 200
1018	;;
1019
1020xenevt)
1021	mkdev xenevt c %xenevt_chr% 0
1022	;;
1023
1024xsd_kva)
1025	mkdev xsd_kva c %xenevt_chr% 1
1026	;;
1027
1028xencons)
1029	mkdev xencons c %xencons_chr% 0
1030	;;
1031
1032ttyEstat)
1033	mkdev ttyEstat c %wsdisplay_chr% 254
1034	;;
1035
1036ttyEcfg)
1037	mkdev ttyEcfg c %wsdisplay_chr% 255
1038	;;
1039
1040ttyE[0-9]*)
1041	unit=${i#ttyE}
1042	mkdev ttyE$unit c %wsdisplay_chr% $unit
1043	;;
1044
1045wsmouse[0-9]*)
1046	unit=${i#wsmouse}
1047	mkdev wsmouse$unit c %wsmouse_chr% $unit
1048	;;
1049
1050wskbd[0-9]*)
1051	unit=${i#wskbd}
1052	mkdev wskbd$unit c %wskbd_chr% $unit
1053	;;
1054
1055fd)
1056	if ! $fdesc_mounted; then
1057		# Create the "fd" subdirectory, and devices "fd/0" to "fd/63"
1058		makedir fd 755
1059		n=0
1060		while [ $n -lt 64 ]
1061		do
1062			mkdev fd/$n c %filedesc_chr% $n 666
1063			n=$(($n + 1))
1064		done
1065	fi
1066	;;
1067
1068wt[0-9]*)
1069	name=wt;  unit=${i#wt};	chr=%wt_chr%;	blk=%wt_blk%
1070	for sub in $unit $(($unit+8)) $(($unit+16))
1071	do
1072		mkdev $name$sub		b $blk $(($sub + 0)) 660 $g_operator
1073		mkdev n$name$sub	b $blk $(($sub + 4)) 660 $g_operator
1074		mkdev r$name$sub	c $chr $(($sub + 0)) 660 $g_operator
1075		mkdev nr$name$sub	c $chr $(($sub + 4)) 660 $g_operator
1076	done
1077	;;
1078
1079md[0-9]*)
1080	makedisk_minimal md ${i#md} %md_blk% %md_chr%
1081	;;
1082
1083fss[0-9]*)
1084	name=fss; unit=${i#fss};	blk=%fss_blk%;	chr=%fss_chr%
1085	mkdev $name$unit	b $blk $unit 660 $g_operator
1086	mkdev r$name$unit	c $chr $unit 660 $g_operator
1087	;;
1088
1089ss[0-9]*)
1090	name=ss;	unit=${i#ss};	chr=%ss_chr%
1091	mkdev $name$unit	c $chr $(($unit * 16 + 0)) 640 $g_operator
1092	mkdev n$name$unit	c $chr $(($unit * 16 + 1)) 640 $g_operator
1093	mkdev en$name$unit	c $chr $(($unit * 16 + 3)) 640 $g_operator
1094	;;
1095
1096ccd[0-9]*|cgd[0-9]*|raid[0-9]*|vnd[0-9]*)
1097	case $i in
1098	ccd*)	name=ccd;	unit=${i#ccd};	blk=%ccd_blk%;	chr=%ccd_chr%;;
1099	cgd*)	name=cgd;	unit=${i#cgd};	blk=%cgd_blk%;	chr=%cgd_chr%;;
1100	raid*)	name=raid;	unit=${i#raid}; blk=%raid_blk%; chr=%raid_chr%;;
1101	vnd*)	name=vnd;	unit=${i#vnd};	blk=%vnd_blk%;	chr=%vnd_chr%;;
1102	esac
1103	%MKDISK% $name $unit $blk $chr
1104	;;
1105
1106sd[0-9]*)
1107	name=sd; unit=${i#sd};	blk=%sd_blk%;	chr=%sd_chr%
1108	%MKDISK% $name $unit $blk $chr
1109	;;
1110
1111ace[0-9]*)
1112	name=ace; unit=${i#ace};	blk=%ace_blk%;		chr=%ace_chr%
1113	%MKDISK% $name $unit $blk $chr
1114	;;
1115
1116eflash[0-9]*)
1117	name=eflash; unit=${i#eflash};	blk=%eflash_blk%;	chr=%eflash_chr%
1118	%MKDISK% $name $unit $blk $chr
1119	;;
1120
1121wd[0-9]*)
1122	name=wd; unit=${i#wd}; blk=%wd_blk%; chr=%wd_chr%
1123	%MKDISK% $name $unit $blk $chr
1124	;;
1125
1126fd[0-9]*)
1127	name=fd; unit=${i#fd}; blk=%fd_blk%; chr=%fd_chr%
1128	%MKDISK% $name $unit $blk $chr
1129	;;
1130
1131ld[0-9]*)
1132	name=ld; unit=${i#ld}; blk=%ld_blk%; chr=%ld_chr%
1133	%MKDISK% $name $unit $blk $chr
1134	;;
1135
1136flash[0-9]*)
1137	unit=${i#flash}
1138	flash=flash$unit
1139	mkdev flash$unit b %flash_blk% $unit
1140	mkdev rflash$unit c %flash_chr% $unit
1141	;;
1142
1143spiflash[0-9]*)
1144	unit=${i#spiflash}
1145	spiflash=spiflash$unit
1146	mkdev spiflash$unit b %spiflash_blk% $unit
1147	;;
1148
1149altmem[0-9]*)
1150	name=altmem; unit=${i#altmem}; blk=%altmem_blk%; chr=%altmem_chr%
1151	%MKDISK% $name $unit $blk $chr
1152	;;
1153
1154bio)
1155	mkdev bio c %bio_chr% 0
1156	;;
1157
1158ed[0-9]*)
1159	name=ed; unit=${i#ed}; blk=%ed_blk%; chr=%ed_chr%
1160	%MKDISK% $name $unit $blk $chr
1161	;;
1162
1163ofdisk[0-9]*)
1164	name=ofdisk; unit=${i#ofdisk}; blk=%ofdisk_blk%; chr=%ofdisk_chr%
1165	%MKDISK% $name $unit $blk $chr
1166	;;
1167
1168xbd[0-9]*)
1169	name=xbd; unit=${i#xbd}; blk=%xbd_blk%; chr=%xbd_chr%
1170	%MKDISK% $name $unit $blk $chr
1171	;;
1172
1173dk[0-9]*)
1174	name=dk; unit=${i#dk}; blk=%dk_blk%; chr=%dk_chr%
1175	mkdev r$name$unit c $chr $unit 0640 $g_operator
1176	mkdev $name$unit b $blk  $unit 0640 $g_operator
1177	;;
1178
1179ttyCY[0-9]*)
1180	# Each unit number creates 32 pairs of {tty,dty} device nodes:
1181	# ttyCY0 => device nodes [td]tyCY000 to [td]tyCY031;
1182	# ttyCY1 => device nodes [td]tyCY032 to [td]tyCY063;
1183	name=tyCY; chr=%cy_chr%; off=32
1184	unit=${i#t${name}}
1185	minor=$(($unit * $off))
1186	eminor=$(($minor + $off))
1187	while [ $minor -lt $eminor ]
1188	do
1189		nminor=000$minor
1190		nminor=${nminor#${nminor%???}}
1191		mkdev t$name$nminor c $chr $(($minor + $dialin )) "" "" $u_uucp
1192		mkdev d$name$nminor c $chr $(($minor + $dialout)) "" "" $u_uucp
1193		minor=$(($minor + 1))
1194	done
1195	;;
1196
1197ttyCZ[0-9]*)
1198	# Each unit number creates 64 pairs of {tty,dty} device nodes:
1199	# ttyCZ0 => device nodes [td]tyCZ0000 to [td]tyCZ0063;
1200	# ttyCZ1 => device nodes [td]tyCZ0064 to [td]tyCZ0127;
1201	name=tyCZ; chr=%cz_chr%; off=64
1202	unit=${i#t${name}}
1203	minor=$(($unit * $off))
1204	eminor=$(($minor + $off))
1205	while [ $minor -lt $eminor ]
1206	do
1207		nminor=0000$minor
1208		nminor=${nminor#${nminor%????}}
1209		mkdev t$name$nminor c $chr $(($minor + $dialin )) "" "" $u_uucp
1210		mkdev d$name$nminor c $chr $(($minor + $dialout)) "" "" $u_uucp
1211		minor=$(($minor + 1))
1212	done
1213	;;
1214
1215
1216tty[0-9]|tty0[0-9])
1217	# some archs have built-in zstty (major %zstty_chr%) instead
1218	# of NS16550; create ttyZ* and hardlink as [dt]ty0*; this
1219	# needs to be before com entry, for archs which have both
1220	unit=${i#tty}
1221	unit=$(($unit + 0))
1222	makedev ttyZ${unit}
1223	lndev ttyZ$unit tty0${unit}
1224	lndev dtyZ$unit dty0${unit}
1225	;;
1226
1227tty[0-9]*)
1228	unit=${i#tty}
1229	ounit=00$unit
1230	ounit=${ounit#${ounit%??}}
1231	mkdev tty$ounit c %com_chr% $(($unit + $dialin )) "" "" $u_uucp
1232	mkdev dty$ounit c %com_chr% $(($unit + $dialout)) "" "" $u_uucp
1233	;;
1234
1235ttyC[0-9]*)
1236		# some archs call com_chr ttyC traditionally
1237	unit=${i#ttyC}; name=ttyC; dname=dtyC; chr=%com_chr%
1238	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1239	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1240	;;
1241
1242ttyh[0-9]*)
1243	unit=${i#ttyh}; name=ttyh; dname=dtyh; chr=%sabtty_chr%
1244	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1245	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1246	;;
1247
1248ttyTX[0-9]*)
1249	unit=${i#ttyTX}; name=ttyTX0; dname=dtyTX0; chr=%txcom_chr%
1250	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1251	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1252	;;
1253
1254ttyZ[0-9]*)
1255	unit=${i#ttyZ}; name=ttyZ; dname=dtyZ; chr=%zstty_chr%
1256	mkdev  $name$unit c $chr $(($unit + $dialin )) "" "" $u_uucp
1257	mkdev $dname$unit c $chr $(($unit + $dialout)) "" "" $u_uucp
1258	;;
1259
1260opty)
1261	# Create 16 device nodes, [pt]typ0 to [pt]typf,
1262	# same as "MAKEDEV pty0".
1263	for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f
1264	do
1265		case $j in
1266		[0-9])	jn=$j ;;
1267		a)	jn=10 ;;
1268		b)	jn=11 ;;
1269		c)	jn=12 ;;
1270		d)	jn=13 ;;
1271		e)	jn=14 ;;
1272		f)	jn=15 ;;
1273		esac
1274		mkdev ttyp$j c %pts_chr% $jn 666
1275		mkdev ptyp$j c %ptc_chr% $jn 666
1276	done
1277	;;
1278
1279pty[0-9]*)
1280	# Each unit number creates up to 16 pairs of {tty,pty} device nodes:
1281	# pty0 => 16 pairs, [tp]typ0 to [tp]typf
1282	# pty1 => 16 pairs, [tp]tyq0 to [tp]tyqf
1283	# pty16 => 16 pairs, [tp]typg to [tp]typv
1284	# pty17 => 16 pairs, [tp]typw to [tp]typL
1285	# pty18 => 14 pairs, [tp]typM to [tp]typZ
1286	warn "$i: creating BSD style tty nodes with ptyfs is a security issue"
1287	class=${i#pty}
1288	d1="p q r s t u v w x y z P Q R S T"
1289	if [ "$class" -ge 64 ]
1290	then
1291		warn "$i: pty unit must be between 0 and 63"
1292		continue
1293	elif [ "$class" -lt 16 ]
1294	then
1295		# pty[p-zP-T][0-9a-f]
1296		offset=0
1297		mult=0
1298		d2="0 1 2 3 4 5 6 7 8 9 a b c d e f"
1299	else
1300		# pty[p-zP-T][g-zA-Z]
1301		class=$(($class - 16))
1302		offset=256
1303		mult=2
1304		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"
1305	fi
1306	start=$(($class * 16))
1307	set -- $d2
1308	nt=$#
1309	s1=$(($start / $nt))
1310	set -- $d1
1311	shift $s1
1312	t1=$1
1313	if [ "$t1" = v ]; then
1314		warn "$i: pty unit conflicts with console ttyv0 device"
1315		continue
1316	fi
1317	s2=$(($start % ($nt - $s1 * $mult)))
1318	set -- $d2
1319	shift $s2
1320	t2=$1
1321	unit=$(($start + $offset - $s1 * $mult))
1322	end=$(($unit + 16))
1323	while [ "$unit" -lt "$end" ]
1324	do
1325		mkdev tty$t1$t2 c %pts_chr% $unit 666
1326		mkdev pty$t1$t2 c %ptc_chr% $unit 666
1327		shift
1328		t2=$1
1329		if [ -z "$t2" ]
1330		then
1331			break
1332		fi
1333		unit=$(($unit + 1))
1334	done
1335	;;
1336
1337stic[0-9]*)
1338	unit=${i#stic}
1339	mkdev stic$unit c %stic_chr% $unit
1340	;;
1341
1342st[0-9]*)
1343	name=st;	unit=${i#st};	chr=%st_chr%;	blk=%st_blk%
1344	mkdev $name$unit	b $blk $(($unit * 16 + 0)) 660 $g_operator
1345	mkdev n$name$unit	b $blk $(($unit * 16 + 1)) 660 $g_operator
1346	mkdev e$name$unit	b $blk $(($unit * 16 + 2)) 660 $g_operator
1347	mkdev en$name$unit	b $blk $(($unit * 16 + 3)) 660 $g_operator
1348	mkdev r$name$unit	c $chr $(($unit * 16 + 0)) 660 $g_operator
1349	mkdev nr$name$unit	c $chr $(($unit * 16 + 1)) 660 $g_operator
1350	mkdev er$name$unit	c $chr $(($unit * 16 + 2)) 660 $g_operator
1351	mkdev enr$name$unit	c $chr $(($unit * 16 + 3)) 660 $g_operator
1352	;;
1353
1354ses[0-9]*|ch[0-9]*|uk[0-9]*)
1355	case $i in
1356	ch*)	name=ch;	unit=${i#ch};	chr=%ch_chr%;;
1357	uk*)	name=uk;	unit=${i#uk};	chr=%uk_chr%;;
1358	ses*)	name=ses;	unit=${i#ses};	chr=%ses_chr%;;
1359	esac
1360	mkdev $name$unit c $chr $unit 640 $g_operator
1361	;;
1362
1363cd[0-9]*)
1364	makedisk_minimal cd ${i#cd} %cd_blk% %cd_chr%
1365	;;
1366
1367mcd[0-9]*)
1368	makedisk_minimal mcd ${i#mcd} %mcd_blk% %mcd_chr%
1369	;;
1370
1371gdrom[0-9]*)
1372	makedisk_minimal gdrom ${i#gdrom} %gdrom_blk% %gdrom_chr%
1373	;;
1374
1375lpt[0-9]*|lpa[0-9]*)
1376	case $i in
1377	lpt*) name=lpt; unit=${i#lpt};	chr=%lpt_chr%;	flags=0;;
1378	lpa*) name=lpa; unit=${i#lpa};	chr=%lpt_chr%;	flags=128;;
1379	esac
1380	mkdev $name$unit c $chr $(($unit + $flags))
1381	mkdev lpt${unit}ctl c $chr $(($unit + 256))
1382	;;
1383
1384bpf)
1385	mkdev bpf	c %bpf_chr% 0
1386	lndev bpf bpf0
1387	;;
1388
1389npf)
1390	mkdev npf	c %npf_chr% 0
1391	;;
1392
1393bthub)
1394	mkdev bthub c %bthub_chr% 0
1395	;;
1396
1397tun[0-9]*)
1398	unit=${i#tun}
1399	mkdev tun$unit c %tun_chr% $unit
1400	;;
1401
1402joy[0-9]*)
1403	unit=${i#joy}
1404	mkdev joy$unit c %joy_chr% $unit
1405	;;
1406
1407ipl)
1408	mkdev ipl	c %ipl_chr% 0
1409	mkdev ipnat	c %ipl_chr% 1
1410	mkdev ipstate	c %ipl_chr% 2
1411	mkdev ipauth	c %ipl_chr% 3
1412	mkdev ipsync	c %ipl_chr% 4
1413	mkdev ipscan	c %ipl_chr% 5
1414	mkdev iplookup	c %ipl_chr% 6
1415	;;
1416
1417pf)
1418	mkdev pf c %pf_chr% 0
1419	;;
1420
1421crypto)
1422	mkdev crypto c %crypto_chr% 0 666
1423	;;
1424
1425cmos)
1426	mkdev cmos c %cmos_chr% 0 644
1427	;;
1428
1429speaker)
1430	mkdev speaker c %spkr_chr% 0
1431	;;
1432
1433lockstat)
1434	mkdev lockstat c %lockstat_chr% 0
1435	;;
1436
1437cpuctl)
1438	mkdev cpuctl c %cpuctl_chr% 0 666
1439	;;
1440
1441audio|audio[0-9]*)
1442	unit=${i#audio}
1443	audio=audio$unit
1444	sound=sound$unit
1445	mixer=mixer$unit
1446	audioctl=audioctl$unit
1447	: ${unit:-0}
1448	mkdev $sound	c %audio_chr% $(($unit + 0))	666
1449	mkdev $audio	c %audio_chr% $(($unit + 128))	666
1450	mkdev $mixer	c %audio_chr% $(($unit + 16))	666
1451	mkdev $audioctl c %audio_chr% $(($unit + 192))	666
1452	;;
1453
1454hdaudio[0-9]*)
1455	unit=${i#hdaudio}
1456	mkdev hdaudio$unit c %hdaudio_chr% $unit 644
1457	;;
1458
1459gpio[0-9]*)
1460	unit=${i#gpio}
1461	mkdev gpio$unit c %gpio_chr% $unit 644
1462	;;
1463
1464rmidi[0-9]*)
1465	unit=${i#rmidi}
1466	mkdev rmidi$unit c %midi_chr% $unit 666
1467	;;
1468
1469music|music[0-9]*)
1470	unit=${i#music}
1471	: ${unit:-0}
1472	mkdev music$unit     c %sequencer_chr% $(($unit + 0))	666
1473	mkdev sequencer$unit c %sequencer_chr% $(($unit + 128)) 666
1474	;;
1475
1476radio|radio[0-9]*)
1477	unit=${i#radio}
1478	: ${unit:-0}
1479	mkdev radio$unit c %radio_chr% $unit 666
1480	;;
1481
1482video|video[0-9]*)
1483	unit=${i#video}
1484	: ${unit:-0}
1485	mkdev video$unit c %video_chr% $unit 666
1486	;;
1487
1488dtv[0-9]*)
1489	unit=${i#dtv}
1490	makedir dvb 755
1491	makedir dvb/adapter$unit 755
1492	mkdev dvb/adapter$unit/frontend0 c %dtv_chr% $(($unit + 0)) 666
1493	mkdev dvb/adapter$unit/demux0 c %dtv_chr% $(($unit + 16)) 666
1494	mkdev dvb/adapter$unit/dvr0 c %dtv_chr% $(($unit + 32)) 666
1495	;;
1496
1497iic[0-9]*)
1498	unit=${i#iic}
1499	: ${unit:-0}
1500	mkdev iic$unit c %iic_chr% $unit 600
1501	;;
1502
1503amr[0-9]*)
1504	unit=${i#amr}
1505	mkdev amr$unit c %amr_chr% $unit
1506	;;
1507
1508apm)
1509	mkdev apm	c %apm_chr% 0 644
1510	mkdev apmctl	c %apm_chr% 8 644
1511	;;
1512
1513apm)
1514		# hpcmips uses `apmdev_chr' instead of `apm_chr'
1515	mkdev apm	c %apmdev_chr% 0 644
1516	mkdev apmctl	c %apmdev_chr% 8 644
1517	;;
1518
1519satlink[0-9]*)
1520	unit=${i#satlink}
1521	mkdev satlink$unit c %satlink_chr% $unit 444
1522	;;
1523
1524random)
1525	mkdev random	c %rnd_chr% 0 444
1526	mkdev urandom	c %rnd_chr% 1 644
1527	;;
1528
1529cfs)
1530	makedev cfs0
1531	;;
1532
1533cfs[0-9]*)
1534	unit=${i#cfs}
1535	mkdev cfs$unit c %vcoda_chr% $unit
1536	;;
1537
1538sysmon)
1539	mkdev sysmon	c %sysmon_chr% 0 644
1540	mkdev watchdog	c %sysmon_chr% 1 644
1541	mkdev power	c %sysmon_chr% 2 640
1542	;;
1543
1544scsibus[0-9]*)
1545	unit=${i#scsibus}
1546	mkdev scsibus$unit c %scsibus_chr% $unit 644
1547	;;
1548
1549bktr)
1550	makedev bktr0 bktr1
1551	lndev	bktr0	bktr
1552	lndev	tuner0	tuner
1553	lndev	vbi0	vbi
1554	;;
1555
1556bktr[0-9]*)
1557	unit=${i#bktr}
1558	mkdev bktr$unit		c %bktr_chr% $(($unit + 0))	444
1559	mkdev tuner$unit	c %bktr_chr% $(($unit + 16))	444
1560	mkdev vbi$unit		c %bktr_chr% $(($unit + 32))	444
1561	;;
1562
1563io)
1564	mkdev		io	c %mem_chr% 14	600
1565	;;
1566
1567iop[0-9]*)
1568	unit=${i#iop}
1569	mkdev iop$unit c %iop_chr% $unit
1570	;;
1571
1572mfi[0-9]*)
1573	unit=${i#mfi}
1574	mkdev mfi$unit c %mfi_chr% $unit
1575	;;
1576
1577mlx[0-9]*)
1578	unit=${i#mlx}
1579	mkdev mlx$unit c %mlx_chr% $unit
1580	;;
1581
1582mly[0-9]*)
1583	unit=${i#mly}
1584	mkdev mly$unit c %mly_chr% $unit
1585	;;
1586
1587twa[0-9]*)
1588	unit=${i#twa}
1589	mkdev twa$unit c %twa_chr% $unit
1590	;;
1591
1592twe[0-9]*)
1593	unit=${i#twe}
1594	mkdev twe$unit c %twe_chr% $unit
1595	;;
1596
1597icp[0-9]*)
1598	unit=${i#icp}
1599	mkdev icp$unit c %icp_chr% $unit
1600	;;
1601
1602agp[0-9]*)
1603	unit=${i#agp}
1604	mkdev agp$unit c %agp_chr% $unit 644
1605	if [ "$unit" = "0" ]; then
1606		lndev agp$unit agpgart
1607	fi
1608	;;
1609
1610pci[0-9]*)
1611	unit=${i#pci}
1612	mkdev pci$unit c %pci_chr% $unit 640
1613	;;
1614
1615dpti[0-9]*)
1616	unit=${i#dpti}
1617	mkdev dpti$unit c %dpti_chr% $unit
1618	;;
1619
1620dpt[0-9]*)
1621	unit=${i#dpt}
1622	mkdev dpt$unit c %dpt_chr% $unit
1623	;;
1624
1625altq)
1626	makedir altq 755
1627	unit=0
1628	for dev in altq cbq wfq afm fifoq red rio localq hfsc cdnr blue priq jobs
1629	do
1630		mkdev altq/$dev c %altq_chr% $unit 644
1631		unit=$(($unit + 1))
1632	done
1633	;;
1634
1635isdn)
1636	mkdev isdn c %isdn_chr% 0
1637	;;
1638
1639isdnctl)
1640	mkdev isdnctl c %isdnctl_chr% 0
1641	;;
1642
1643isdnbchan[0-9]*)
1644	unit=${i#isdnbchan}
1645	mkdev isdnbchan$unit c %isdnbchan_chr% $unit
1646	;;
1647
1648isdnteld[0-9]*)
1649	unit=${i#isdnteld}
1650	mkdev isdnteld$unit c %isdntel_chr% $(($unit + 64))
1651	;;
1652
1653isdntel[0-9]*)
1654	unit=${i#isdntel}
1655	mkdev isdntel$unit c %isdntel_chr% $unit
1656	;;
1657
1658isdntrc[0-9]*)
1659	unit=${i#isdntrc}
1660	mkdev isdntrc$unit c %isdntrc_chr% $unit
1661	;;
1662
1663wsfont)
1664	mkdev wsfont c %wsfont_chr% 0
1665	;;
1666
1667cir[0-9]*)
1668	unit=${i#cir}
1669	mkdev cir$unit c %cir_chr% $unit 666
1670	;;
1671
1672irframe[0-9]*)
1673	unit=${i#irframe}
1674	mkdev irframe$unit c %irframe_chr% $unit
1675	;;
1676
1677fcom[0-9]*)
1678	unit=${i#fcom}
1679	mkdev fcom$unit c %fcom_chr% $unit "" "" $u_uucp
1680	;;
1681
1682openfirm)
1683	mkdev openfirm c %openfirm_chr% 0 444
1684	;;
1685
1686pad[0-9]*)
1687	unit=${i#pad}
1688	mkdev pad$unit c %pad_chr% $unit 444
1689	;;
1690
1691nvram)
1692	mkdev nvram c %nvram_chr% 0 644
1693	;;
1694
1695rtc)
1696	mkdev rtc c %rtc_chr% 0 644
1697	;;
1698
1699clockctl)
1700	mkdev clockctl c %clockctl_chr% 0 660 $g_ntpd
1701	;;
1702
1703nsmb)
1704	makedev nsmb0 nsmb1 nsmb2 nsmb3
1705	;;
1706
1707nsmb[0-9]*)
1708	unit=${i#nsmb}
1709	mkdev nsmb$unit c %nsmb_chr% $unit 644
1710	;;
1711
1712kttcp)
1713	mkdev kttcp c %kttcp_chr% 0
1714	;;
1715
1716dmoverio)
1717	mkdev dmoverio c %dmoverio_chr% 0 644
1718	;;
1719
1720veriexec)
1721	mkdev veriexec c %veriexec_chr% 0 600
1722	;;
1723
1724ttyv[0-9]*)
1725	unit=${i#ttyv}
1726	mkdev ttyv$unit c %pc_chr% $unit
1727	;;
1728
1729# arm, acorn32
1730ttyv[0-9]*)
1731	unit=${i#ttyv}
1732	mkdev ttyv$unit c %physcon_chr% $unit
1733	;;
1734
1735arcpp[0-9]*)
1736	unit=${i#arcpp}
1737	mkdev arcpp$unit c %arcpp_chr% $unit
1738	;;
1739
1740par[0-9]*)
1741	unit=${i#par}
1742	case $unit in
1743	0)
1744		mkdev par$unit c %par_chr% $unit
1745		;;
1746	*)
1747		warn "bad unit for par in: $i"
1748		;;
1749	esac
1750	;;
1751
1752cpi[0-9]*)
1753	unit=${i#cpi}
1754	mkdev cpi$unit c %cpi_chr% $unit
1755	;;
1756
1757ite[0-9]*|ttye[0-9]*)
1758	case $i in
1759	ite*)	unit=${i#ite};;
1760	ttye*)	unit=${i#ttye};;
1761	esac
1762	mkdev ttye$unit c %ite_chr% $unit
1763	;;
1764
1765pms[0-9]*)
1766	unit=${i#pms}
1767	mkdev pms$unit c %opms_chr% $unit
1768	;;
1769
1770qms[0-9]*)
1771	unit=${i#qms}
1772	mkdev qms$unit c %qms_chr% $unit
1773	;;
1774
1775lms[0-9]*)
1776	unit=${i#lms}
1777	mkdev lms$unit c %lms_chr% $unit
1778	;;
1779
1780mms[0-9]*)
1781	unit=${i#mms}
1782	mkdev mms$unit c %mms_chr% $unit
1783	;;
1784
1785mouse-pms[0-9]*|mouse-qms[0-9]*)
1786	case $i in
1787	mouse-pms*) name=pms ;;
1788	mouse-qms*) name=qms ;;
1789	esac
1790	unit=${i#mouse-${name}}
1791	lndev $name$unit mouse
1792	;;
1793
1794kbd)
1795	mkdev kbd c %kbd_chr% 0
1796	;;
1797
1798kbdctl)
1799	mkdev kbdctl c %kbd_chr% 1
1800	;;
1801
1802vidcconsole0)
1803	mkdev vidcconsole0 c %vidcconsole_chr% 0 640
1804	;;
1805
1806view[0-9]*)
1807	unit=${i#view}
1808	mkdev view$unit c %view_chr% $unit 666
1809	;;
1810
1811mouse[0-9]*)
1812	unit=${i#mouse}
1813	case $unit in
1814	0|1)
1815		mkdev mouse$unit c %ms_chr% $unit 666
1816		if [ $unit = 0 ]; then
1817			lndev mouse$unit mouse
1818		fi
1819		;;
1820	*)
1821		warn "bad unit for mouse in: $i"
1822		;;
1823	esac
1824	;;
1825
1826panel)
1827	mkdev panel0 c %panel_chr% 0 660
1828	;;
1829
1830tslcd)
1831	mkdev tslcd0 c %tslcd_chr% 0 660
1832	;;
1833
1834ipty)
1835	mkdev ttyp0 c %pts_chr% 0 666
1836	mkdev ttyp1 c %pts_chr% 1 666
1837	mkdev ptyp0 c %ptc_chr% 0 666
1838	mkdev ptyp1 c %ptc_chr% 1 666
1839	;;
1840
1841ptm)
1842	makedir pts 755
1843	mkdev ptmx c %ptm_chr% 0 666
1844	mkdev ptm c %ptm_chr% 1 666
1845	;;
1846
1847grf[0-9]*)
1848	unit=${i#grf}
1849	mkdev grf$unit c %grf_chr% $unit 666
1850	;;
1851
1852etvme)
1853	mkdev etvme c %et_chr% 0
1854	;;
1855
1856leo[0-9]*)
1857	unit=${i#leo}
1858	mkdev leo$unit c %leo_chr% $unit
1859	;;
1860
1861scif[0-9]*)
1862	unit=${i#scif}
1863	mkdev scif$unit c %scif_chr% $(($unit + $dialin )) "" "" $u_uucp
1864	mkdev dscif$unit c %scif_chr% $(($unit + $dialout)) "" "" $u_uucp
1865	;;
1866
1867sci[0-9]*)
1868	unit=${i#sci}
1869	mkdev sci$unit c %sci_chr% $(($unit + $dialin )) "" "" $u_uucp
1870	mkdev dsci$unit c %sci_chr% $(($unit + $dialout)) "" "" $u_uucp
1871	;;
1872
1873maple[ABCD]|maple[ABCD][0-9]*)
1874	case $i in
1875	mapleA*) name="mapleA"; unit=0;;
1876	mapleB*) name="mapleB"; unit=1;;
1877	mapleC*) name="mapleC"; unit=2;;
1878	mapleD*) name="mapleD"; unit=3;;
1879	esac
1880	subunit=${i#$name}
1881	mkdev $name$subunit c %maple_chr% $(($unit * 8 + 0$subunit))
1882	;;
1883
1884mmem[0-9]*)
1885	unit=${i#mmem}
1886	for pt in 0	# 1 2 3 4 ... 255
1887	do
1888#		mkdev mmem${unit}.${pt}a  b %mmem_blk% $(($unit * 4096 + $pt * 16 + 0)) 640 $g_operator
1889		mkdev mmem${unit}.${pt}c  b %mmem_blk% $(($unit * 4096 + $pt * 16 + 2)) 640 $g_operator
1890#		mkdev rmmem${unit}.${pt}a c %mmem_chr% $(($unit * 4096 + $pt * 16 + 0)) 640 $g_operator
1891		mkdev rmmem${unit}.${pt}c c %mmem_chr% $(($unit * 4096 + $pt * 16 + 2)) 640 $g_operator
1892	done
1893	;;
1894
1895mlcd[0-9]*)
1896	unit=${i#mlcd}
1897	for pt in 0	# 1 2 3 4 ... 255
1898	do
1899		mkdev mlcd${unit}.${pt} c %mlcd_chr% $(($unit * 256 + $pt)) 640 $g_operator
1900	done
1901	;;
1902
1903ixpcom[0-9]*)
1904	unit=${i#ixpcom}
1905	mkdev ixpcom$unit c %ixpcom_chr% $unit "" "" $u_uucp
1906	;;
1907
1908epcom[0-9]*)
1909	unit=${i#epcom}
1910	mkdev epcom$unit c %epcom_chr% $unit "" "" $u_uucp
1911	;;
1912
1913plcom[0-9]*)
1914	unit=${i#plcom}
1915	mkdev plcom$unit c %plcom_chr% $unit "" "" $u_uucp
1916	;;
1917
1918wmcom[0-9]*)
1919	unit=${i#wmcom}
1920	mkdev wmcom$unit c %wmcom_chr% $unit "" "" $u_uucp
1921	;;
1922
1923ucbsnd)
1924	mkdev ucbsnd c %ucbsnd_chr% 0 666
1925	;;
1926
1927adb)
1928	mkdev adb c %aed_chr% 0 666
1929	;;
1930
1931asc[0-9]*)
1932	unit=${i#asc}
1933	mkdev asc$unit c %asc_chr% $unit 666
1934	;;
1935
1936bwtwo[0-9]*)
1937	unit=${i#bwtwo}
1938	mkdev bwtwo$unit c %bwtwo_chr% $unit 666
1939	;;
1940
1941cgtwo[0-9]*)
1942	unit=${i#cgtwo}
1943	mkdev cgtwo$unit c %cgtwo_chr% $unit 666
1944	;;
1945
1946cgthree[0-9]*)
1947	unit=${i#cgthree}
1948	mkdev cgthree$unit c %cgthree_chr% $unit 666
1949	;;
1950
1951cgfour[0-9]*)
1952	unit=${i#cgfour}
1953	mkdev cgfour$unit c %cgfour_chr% $unit 666
1954	;;
1955
1956cgsix[0-9]*)
1957	unit=${i#cgsix}
1958	mkdev cgsix$unit c %cgsix_chr% $unit 666
1959	;;
1960
1961cgeight[0-9]*)
1962	unit=${i#cgeight}
1963	mkdev cgeight$unit c %cgeight_chr% $unit 666
1964	;;
1965
1966tcx[0-9]*)
1967	unit=${i#tcx}
1968	mkdev tcx$unit c %tcx_chr% $unit 666
1969	;;
1970
1971xd[0-9]*|xy[0-9]*)
1972	case $i in
1973	xd*)	name=xd; unit=${i#xd}; blk=%xd_blk%;	chr=%xd_chr%;;
1974	xy*)	name=xy; unit=${i#xy}; blk=%xy_blk%;	chr=%xy_chr%;;
1975	esac
1976	%MKDISK% $name $unit $blk $chr
1977	;;
1978
1979magma[0-9]*)
1980	unit=${i#magma}
1981	if [ 0$unit -gt 3 ]; then
1982		warn "bad unit for $i: $unit"
1983		break
1984	fi
1985	for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f
1986	do
1987		case $j in
1988		[0-9])	jn=$j ;;
1989		a)	jn=10 ;;
1990		b)	jn=11 ;;
1991		c)	jn=12 ;;
1992		d)	jn=13 ;;
1993		e)	jn=14 ;;
1994		f)	jn=15 ;;
1995		esac
1996		mkdev tty$unit$j c %mtty_chr% $(($unit * 64 + $jn))
1997	done
1998	mkdev bpp${unit}0 c %mbpp_chr% $(($unit * 64 + 0))
1999	mkdev bpp${unit}1 c %mbpp_chr% $(($unit * 64 + 1))
2000	;;
2001
2002clcd[0-9]*)
2003	unit=${i#clcd}
2004	if [ 0$unit -gt 7 ]; then
2005		warn "bad unit for $i: $unit"
2006		break
2007	fi
2008	for j in 0 1 2 3 4 5 6 7
2009	do
2010		mkdev ttyA$unit$j c %clcd_chr% $(($unit * 8 + $j + $dialin)) "" "" $u_uucp
2011		mkdev dtyA$unit$j c %clcd_chr% $(($unit * 8 + $j + $dialout)) "" "" $u_uucp
2012	done
2013	;;
2014
2015spif[0-9]*)
2016	unit=${i#spif}
2017	if [ 0$unit -gt 3 ]; then
2018		warn "bad unit for $i: $unit"
2019		break
2020	fi
2021	for j in 0 1 2 3 4 5 6 7; do
2022		mkdev ttyS$unit$j c %stty_chr% $(($unit * 64 + $j)) "" "" $u_uucp
2023	done
2024	mkdev bppS${unit}0 c %sbpp_chr% $(($unit * 64 + 0))
2025	mkdev bppS${unit}1 c %sbpp_chr% $(($unit * 64 + 1))
2026	;;
2027
2028bpp|bpp[0-9]*)
2029	unit=${i#bpp}
2030	mkdev bpp$unit c %bpp_chr% $(($unit + 0))
2031	;;
2032
2033tctrl[0-9]*)
2034	unit=${i#tctrl}
2035	mkdev tctrl$unit c %tctrl_chr% $unit 666
2036	;;
2037
2038bmd[0-9]*)
2039	unit=${i#bmd}
2040	mkdev bmd${unit}a  b %bmd_blk% $(($unit * 8 + 0)) 640 $g_operator
2041	mkdev bmd${unit}c  b %bmd_blk% $(($unit * 8 + 2)) 640 $g_operator
2042	mkdev rbmd${unit}a c %bmd_chr% $(($unit * 8 + 0)) 640 $g_operator
2043	mkdev rbmd${unit}c c %bmd_chr% $(($unit * 8 + 2)) 640 $g_operator
2044	;;
2045
2046sram)
2047	mkdev sram c %sram_chr% 0 644
2048	;;
2049
2050ttyS[0-9]*)
2051	unit=${i#ttyS}
2052	mkdev ttyS$unit c %sacom_chr% $(($unit + $dialin )) "" "" $u_uucp
2053	mkdev dtyS$unit c %sacom_chr% $(($unit + $dialout)) "" "" $u_uucp
2054	;;
2055
2056atabus[0-9]*)
2057	unit=${i#atabus}
2058	mkdev atabus$unit c %atabus_chr% $unit 644
2059	;;
2060
2061drm[0-9]*)
2062	unit=${i#drm}
2063	makedir dri 755
2064	mkdev dri/card$unit c %drm_chr% $unit 660
2065	;;
2066
2067drvctl)
2068	mkdev drvctl c %drvctl_chr% 0 644
2069	;;
2070
2071isv)
2072	mkdev isv c %isv_chr% 0 644
2073	;;
2074
2075tap|tap[0-9]*)
2076	unit=${i#tap}
2077	case "$unit" in
2078	[0-9]*)
2079		mkdev tap${unit} c %tap_chr% ${unit} 600
2080		;;
2081	"")
2082		mkdev tap c %tap_chr% 0xfffff 600
2083		;;
2084	esac
2085	;;
2086
2087tpm)
2088	mkdev tpm c %tpm_chr% 0 600
2089	;;
2090
2091dtrace)
2092	makedir dtrace 755
2093	mkdev dtrace/dtrace c %dtrace_chr% 0 600
2094	;;
2095
2096fw[0-9]*)
2097	unit=${i#fw}
2098	for j in 0 1 2 3
2099	do
2100		mkdev fw${unit}.${j} c %fw_chr% $((${unit} * 256 + ${j})) 660 ${g_operator}
2101		mkdev fwmem${unit}.${j} c %fw_chr% $((65536 + ${unit} * 256 + ${j})) 660 ${g_operator}
2102	done
2103	;;
2104
2105# create putter device and symlinks for all subsystems using it
2106putter)
2107	mkdev putter c %putter_chr% 0 600
2108	mkdev pud c %putter_chr% 1 600
2109	lndev putter puffs
2110	;;
2111
2112zfs)
2113	mkdev zfs c %zfs_chr% 0 600
2114	makedir zpool 755
2115	;;
2116
2117iscsi[0-9]*)
2118	unit=${i#iscsi}
2119	mkdev iscsi${unit} c %iscsi_chr% 0 600
2120	;;
2121
2122vchiq)
2123	mkdev vchiq c %vchiq_chr% 0 600
2124	;;
2125
2126midevend)
2127%MI_DEVICES_END%
2128local)
2129	if [ -f "$0.local" ]; then
2130		umask 0
2131		if [ -n "$count_nodes" ]; then
2132			count_nodes=$((count_nodes + \
2133			    $(linecount "$("$HOST_SH" "$0.local" $opts -s all)") ))
2134		else
2135			"$HOST_SH" "$0.local" $opts all
2136		fi
2137		umask 077
2138	fi
2139	;;
2140
2141*)
2142	warn "$i: unknown device"
2143	;;
2144
2145esac
2146done
2147
2148}
2149
2150
2151# three variants of disk partitions - max 8, max 16, max 16 with highpartoffset
2152# hack; only the one used by port is retained in final MAKEDEV script
2153# routine is called as:
2154# makedisk name unit blk chr
2155makedisk_p8()
2156{
2157	name="$1"; unit="$2"; blk="$3"; chr="$4"
2158
2159	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2160	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2161	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2162	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2163	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2164	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2165	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2166	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2167	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2168	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2169	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2170	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2171	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2172	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2173	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2174	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2175}
2176
2177makedisk_p12high()
2178{
2179	ho=524280	# offset for partition 9 to 11 (same as ...p16high)
2180	name="$1"; unit="$2"; blk="$3"; chr="$4"
2181
2182	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2183	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2184	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2185	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2186	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2187	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2188	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2189	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2190	mkdev ${name}${unit}i	b $blk $(($unit * 8 + $ho + 8)) 640 $g_operator
2191	mkdev ${name}${unit}j	b $blk $(($unit * 8 + $ho + 9)) 640 $g_operator
2192	mkdev ${name}${unit}k	b $blk $(($unit * 8 + $ho + 10)) 640 $g_operator
2193	mkdev ${name}${unit}l	b $blk $(($unit * 8 + $ho + 11)) 640 $g_operator
2194	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2195	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2196	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2197	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2198	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2199	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2200	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2201	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2202	mkdev r${name}${unit}i	c $chr $(($unit * 8 + $ho + 8)) 640 $g_operator
2203	mkdev r${name}${unit}j	c $chr $(($unit * 8 + $ho + 9)) 640 $g_operator
2204	mkdev r${name}${unit}k	c $chr $(($unit * 8 + $ho + 10)) 640 $g_operator
2205	mkdev r${name}${unit}l	c $chr $(($unit * 8 + $ho + 11)) 640 $g_operator
2206}
2207
2208makedisk_p16()
2209{
2210	name="$1"; unit="$2"; blk="$3"; chr="$4"
2211
2212	mkdev ${name}${unit}a	b $blk $(($unit * 16 + 0))	640 $g_operator
2213	mkdev ${name}${unit}b	b $blk $(($unit * 16 + 1))	640 $g_operator
2214	mkdev ${name}${unit}c	b $blk $(($unit * 16 + 2))	640 $g_operator
2215	mkdev ${name}${unit}d	b $blk $(($unit * 16 + 3))	640 $g_operator
2216	mkdev ${name}${unit}e	b $blk $(($unit * 16 + 4))	640 $g_operator
2217	mkdev ${name}${unit}f	b $blk $(($unit * 16 + 5))	640 $g_operator
2218	mkdev ${name}${unit}g	b $blk $(($unit * 16 + 6))	640 $g_operator
2219	mkdev ${name}${unit}h	b $blk $(($unit * 16 + 7))	640 $g_operator
2220	mkdev ${name}${unit}i	b $blk $(($unit * 16 + 8))	640 $g_operator
2221	mkdev ${name}${unit}j	b $blk $(($unit * 16 + 9))	640 $g_operator
2222	mkdev ${name}${unit}k	b $blk $(($unit * 16 + 10))	640 $g_operator
2223	mkdev ${name}${unit}l	b $blk $(($unit * 16 + 11))	640 $g_operator
2224	mkdev ${name}${unit}m	b $blk $(($unit * 16 + 12))	640 $g_operator
2225	mkdev ${name}${unit}n	b $blk $(($unit * 16 + 13))	640 $g_operator
2226	mkdev ${name}${unit}o	b $blk $(($unit * 16 + 14))	640 $g_operator
2227	mkdev ${name}${unit}p	b $blk $(($unit * 16 + 15))	640 $g_operator
2228	mkdev r${name}${unit}a	c $chr $(($unit * 16 + 0))	640 $g_operator
2229	mkdev r${name}${unit}b	c $chr $(($unit * 16 + 1))	640 $g_operator
2230	mkdev r${name}${unit}c	c $chr $(($unit * 16 + 2))	640 $g_operator
2231	mkdev r${name}${unit}d	c $chr $(($unit * 16 + 3))	640 $g_operator
2232	mkdev r${name}${unit}e	c $chr $(($unit * 16 + 4))	640 $g_operator
2233	mkdev r${name}${unit}f	c $chr $(($unit * 16 + 5))	640 $g_operator
2234	mkdev r${name}${unit}g	c $chr $(($unit * 16 + 6))	640 $g_operator
2235	mkdev r${name}${unit}h	c $chr $(($unit * 16 + 7))	640 $g_operator
2236	mkdev r${name}${unit}i	c $chr $(($unit * 16 + 8))	640 $g_operator
2237	mkdev r${name}${unit}j	c $chr $(($unit * 16 + 9))	640 $g_operator
2238	mkdev r${name}${unit}k	c $chr $(($unit * 16 + 10))	640 $g_operator
2239	mkdev r${name}${unit}l	c $chr $(($unit * 16 + 11))	640 $g_operator
2240	mkdev r${name}${unit}m	c $chr $(($unit * 16 + 12))	640 $g_operator
2241	mkdev r${name}${unit}n	c $chr $(($unit * 16 + 13))	640 $g_operator
2242	mkdev r${name}${unit}o	c $chr $(($unit * 16 + 14))	640 $g_operator
2243	mkdev r${name}${unit}p	c $chr $(($unit * 16 + 15))	640 $g_operator
2244}
2245
2246makedisk_p16high()
2247{
2248	ho=524280	# offset for partition 9 to 16
2249	name="$1"; unit="$2"; blk="$3"; chr="$4"
2250
2251	mkdev ${name}${unit}a	b $blk $(($unit * 8 + 0))	640 $g_operator
2252	mkdev ${name}${unit}b	b $blk $(($unit * 8 + 1))	640 $g_operator
2253	mkdev ${name}${unit}c	b $blk $(($unit * 8 + 2))	640 $g_operator
2254	mkdev ${name}${unit}d	b $blk $(($unit * 8 + 3))	640 $g_operator
2255	mkdev ${name}${unit}e	b $blk $(($unit * 8 + 4))	640 $g_operator
2256	mkdev ${name}${unit}f	b $blk $(($unit * 8 + 5))	640 $g_operator
2257	mkdev ${name}${unit}g	b $blk $(($unit * 8 + 6))	640 $g_operator
2258	mkdev ${name}${unit}h	b $blk $(($unit * 8 + 7))	640 $g_operator
2259	mkdev ${name}${unit}i	b $blk $(($unit * 8 + $ho + 8)) 640 $g_operator
2260	mkdev ${name}${unit}j	b $blk $(($unit * 8 + $ho + 9)) 640 $g_operator
2261	mkdev ${name}${unit}k	b $blk $(($unit * 8 + $ho + 10)) 640 $g_operator
2262	mkdev ${name}${unit}l	b $blk $(($unit * 8 + $ho + 11)) 640 $g_operator
2263	mkdev ${name}${unit}m	b $blk $(($unit * 8 + $ho + 12)) 640 $g_operator
2264	mkdev ${name}${unit}n	b $blk $(($unit * 8 + $ho + 13)) 640 $g_operator
2265	mkdev ${name}${unit}o	b $blk $(($unit * 8 + $ho + 14)) 640 $g_operator
2266	mkdev ${name}${unit}p	b $blk $(($unit * 8 + $ho + 15)) 640 $g_operator
2267	mkdev r${name}${unit}a	c $chr $(($unit * 8 + 0))	640 $g_operator
2268	mkdev r${name}${unit}b	c $chr $(($unit * 8 + 1))	640 $g_operator
2269	mkdev r${name}${unit}c	c $chr $(($unit * 8 + 2))	640 $g_operator
2270	mkdev r${name}${unit}d	c $chr $(($unit * 8 + 3))	640 $g_operator
2271	mkdev r${name}${unit}e	c $chr $(($unit * 8 + 4))	640 $g_operator
2272	mkdev r${name}${unit}f	c $chr $(($unit * 8 + 5))	640 $g_operator
2273	mkdev r${name}${unit}g	c $chr $(($unit * 8 + 6))	640 $g_operator
2274	mkdev r${name}${unit}h	c $chr $(($unit * 8 + 7))	640 $g_operator
2275	mkdev r${name}${unit}i	c $chr $(($unit * 8 + $ho + 8)) 640 $g_operator
2276	mkdev r${name}${unit}j	c $chr $(($unit * 8 + $ho + 9)) 640 $g_operator
2277	mkdev r${name}${unit}k	c $chr $(($unit * 8 + $ho + 10)) 640 $g_operator
2278	mkdev r${name}${unit}l	c $chr $(($unit * 8 + $ho + 11)) 640 $g_operator
2279	mkdev r${name}${unit}m	c $chr $(($unit * 8 + $ho + 12)) 640 $g_operator
2280	mkdev r${name}${unit}n	c $chr $(($unit * 8 + $ho + 13)) 640 $g_operator
2281	mkdev r${name}${unit}o	c $chr $(($unit * 8 + $ho + 14)) 640 $g_operator
2282	mkdev r${name}${unit}p	c $chr $(($unit * 8 + $ho + 15)) 640 $g_operator
2283}
2284
2285# make only the very few basic disk device nodes - 'a' partition
2286# and raw partition
2287makedisk_minimal()
2288{
2289	name=$1; unit=$2; blk=$3; chr=$4
2290	doff=%DISKMINOROFFSET%
2291	ro=%RAWDISK_OFF%
2292	rn=%RAWDISK_NAME%
2293
2294	mkdev ${name}${unit}a	b $blk $(($unit * $doff + 0))	640 $g_operator
2295	mkdev ${name}${unit}$rn b $blk $(($unit * $doff + $ro)) 640 $g_operator
2296	mkdev r${name}${unit}a	c $chr $(($unit * $doff + 0))	640 $g_operator
2297	mkdev r${name}${unit}$rn c $chr $(($unit * $doff + $ro)) 640 $g_operator
2298}
2299
2300# create_mfs_dev nodes
2301#	Create a memory file system for a given number of device nodes,
2302#	and mount it.  Attempts to use mount_tmpfs, or falls back to
2303#	mount_mfs.
2304#
2305#	If do_redirect, then also redirect output to the console.
2306#
2307create_mfs_dev()
2308{
2309	ndevnodes=${1-1200}
2310	dev_mountpoint=${PWD:-/dev}
2311
2312	# Number of inodes is the specified number of device nodes, plus
2313	# a margin to allow for extra device nodes created later.
2314	ninode=$((ndevnodes * 11 / 10))
2315	# Add 2 reserved inodes (needed for both mfs and tmpfs), and round
2316	# up to a multiple of 32 (needed for mfs, not needed for tmpfs).
2317	ninode=$(( (ninode + 2 + 31) / 32 * 32 ))
2318	# Try tmpfs; if that fails try mfs.
2319	#
2320	# For tmpfs, allocate 16KB and 512 byte per node.
2321	# Actual requirements are much lower, but the size limit
2322	# is only intended to avoid accidental writing to /dev.
2323	fs_bytes=$((16384 + ninode * 512))
2324	if mount_tmpfs -s $fs_bytes -n $ninode -m 0755 \
2325		-o union tmpfs "$dev_mountpoint"
2326	then
2327		fstype=tmpfs
2328	else
2329		# This file system size calculation is exact for mount_mfs(8)
2330		# with 512-byte sectors.  40960 bytes (80 blocks) is the
2331		# minimum size allowed by mount_mfs.
2332		fs_bytes=$((8192 + 2 * 8192 + 4096 + ninode*512 + 8192))
2333		[ "$fs_bytes" -lt 40960 ] && fs_bytes=40960
2334		fs_blocks=$((fs_bytes/512))
2335		if mount_mfs -b 4096 -f 512 -s $fs_blocks -n $ninode -p 0755 \
2336		    -o union swap "$dev_mountpoint"
2337		then
2338			fstype=mfs
2339		else
2340			die "Failed to create memory file system"
2341		fi
2342	fi
2343
2344	# Our current directory was in the lower file system; change it to
2345	# the newly mounted upper file system.
2346	cd "$dev_mountpoint"
2347
2348	if $do_redirect; then
2349		# Redirect stdout and stderr to console
2350		${MKNOD} -m 600 -g 0 -u 0 temp_console c %CONSOLE_CMAJOR% 0
2351		exec >temp_console 2>&1
2352		rm temp_console
2353	fi
2354
2355	echo "Created $fstype $dev_mountpoint" \
2356		"($fs_bytes byte, $ninode inodes)"
2357}
2358
2359#
2360# MAIN: If MAKEDEV_AS_LIBRARY is set, then we are being used as a
2361# function library, so just return.  Otherwise, do all the real work.
2362#
2363[ -n "${MAKEDEV_AS_LIBRARY}" ] && return
2364makedev_main makedev ${1+"$@"}
2365