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