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