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