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