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