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