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