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