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