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