ok, the hp300 port still needs config.old
authorderaadt <deraadt@openbsd.org>
Thu, 18 Apr 1996 21:32:46 +0000 (21:32 +0000)
committerderaadt <deraadt@openbsd.org>
Thu, 18 Apr 1996 21:32:46 +0000 (21:32 +0000)
15 files changed:
usr.sbin/Makefile
usr.sbin/config.old/Makefile [new file with mode: 0644]
usr.sbin/config.old/config.h [new file with mode: 0644]
usr.sbin/config.old/config.old.8 [new file with mode: 0644]
usr.sbin/config.old/config.y [new file with mode: 0644]
usr.sbin/config.old/lang.l [new file with mode: 0644]
usr.sbin/config.old/main.c [new file with mode: 0644]
usr.sbin/config.old/mkglue.c [new file with mode: 0644]
usr.sbin/config.old/mkheaders.c [new file with mode: 0644]
usr.sbin/config.old/mkioconf.c [new file with mode: 0644]
usr.sbin/config.old/mkmakefile.c [new file with mode: 0644]
usr.sbin/config.old/mkswapconf.c [new file with mode: 0644]
usr.sbin/config.old/mkubglue.c [new file with mode: 0644]
usr.sbin/config.old/specfile.c [new file with mode: 0644]
usr.sbin/config.old/specfile.h [new file with mode: 0644]

index 27cce19..c85fd5d 100644 (file)
@@ -1,5 +1,5 @@
 #      from: @(#)Makefile      5.6.1.2 (Berkeley) 5/8/91
-#      $Id: Makefile,v 1.7 1996/01/07 02:34:20 dm Exp $
+#      $Id: Makefile,v 1.8 1996/04/18 21:32:46 deraadt Exp $
 
 # not yet done: catman
 
@@ -28,7 +28,7 @@ SUBDIR+=grfconfig iteconfig videomode
 .elif ${MACHINE} == "atari"
 SUBDIR+=iteconfig
 .elif ${MACHINE} == "hp300"
-SUBDIR+=grfinfo hilinfo
+SUBDIR+=grfinfo hilinfo config.old
 .elif ${MACHINE} == "i386"
 SUBDIR+=bad144 
 .elif ${MACHINE} == "pmax"
diff --git a/usr.sbin/config.old/Makefile b/usr.sbin/config.old/Makefile
new file mode 100644 (file)
index 0000000..14b80ac
--- /dev/null
@@ -0,0 +1,14 @@
+#      from: @(#)Makefile      5.12 (Berkeley) 1/16/91
+#      $NetBSD: Makefile,v 1.11 1995/08/17 17:22:06 thorpej Exp $
+
+PROG=  config.old
+BINDIR=        /usr/sbin
+CFLAGS+=-I. -I${.CURDIR}
+SRCS=  config.c main.c lang.c mkioconf.c mkmakefile.c mkglue.c mkheaders.c \
+       mkswapconf.c specfile.c
+MAN=   config.old.8
+LDADD+=        -ll
+DPADD+=        ${LIBL}
+CLEANFILES+=y.tab.h lang.c config.c y.tab.c
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/config.old/config.h b/usr.sbin/config.old/config.h
new file mode 100644 (file)
index 0000000..7b4ccc9
--- /dev/null
@@ -0,0 +1,223 @@
+/*     $NetBSD: config.h,v 1.19 1995/08/17 17:22:08 thorpej Exp $      */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from: @(#)config.h      5.14 (Berkeley) 7/1/91
+ */
+
+/*
+ * Config.
+ */
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        NODEV   ((dev_t)-1)
+
+struct name_expr {
+       int type;
+       char *name;
+       struct name_expr *next,*left,*right;
+};
+
+struct file_list {
+       struct  file_list *f_next;      
+       char    *f_fn;                  /* the name */
+       u_char  f_type;                 /* see below */
+       u_char  f_flags;                /* see below */
+       u_char  f_was_driver;    /* to handle un-included pseudo-drivers*/
+       u_char  f_needs_count;   /* to handle un-included pseudo-drivers*/
+       char    *f_special;             /* special make rule if present */
+       struct  name_expr *f_needs;
+       struct  name_expr *f_countname;
+       /*
+        * Random values:
+        *      swap space parameters for swap areas
+        *      root device, etc. for system specifications
+        */
+       union {
+               struct {                /* when swap specification */
+                       dev_t   fuw_swapdev;
+                       int     fuw_swapsize;
+               } fuw;
+               struct {                /* when system specification */
+                       dev_t   fus_rootdev;
+                       dev_t   fus_dumpdev;
+               } fus;
+               struct {                /* when component dev specification */
+                       dev_t   fup_compdev;
+                       int     fup_compinfo;
+               } fup;
+       } fun;
+#define        f_swapdev       fun.fuw.fuw_swapdev
+#define        f_swapsize      fun.fuw.fuw_swapsize
+#define        f_rootdev       fun.fus.fus_rootdev
+#define        f_dumpdev       fun.fus.fus_dumpdev
+#define f_compdev      fun.fup.fup_compdev
+#define f_compinfo     fun.fup.fup_compinfo
+};
+
+/*
+ * Types.
+ */
+#define DRIVER         1
+#define NORMAL         2
+#define        INVISIBLE       3
+#define        PROFILING       4
+#define        SYSTEMSPEC      5
+#define        SWAPSPEC        6
+#define COMPDEVICE     7
+#define COMPSPEC       8
+
+/*
+ * Attributes (flags).
+ */
+#define        CONFIGDEP       0x1
+#define DUPLICATE       0x2
+
+struct idlst {
+       char    *id;
+       struct  idlst *id_next;
+};
+
+struct device {
+       int     d_type;                 /* CONTROLLER, DEVICE, bus adaptor */
+       struct  device *d_conn;         /* what it is connected to */
+       char    *d_name;                /* name of device (e.g. rk11) */
+       struct  idlst *d_vec;           /* interrupt vectors */
+       int     d_pri;                  /* interrupt priority */
+       int     d_addr;                 /* address of csr */
+       int     d_unit;                 /* unit number */
+       int     d_drive;                /* drive number */
+       int     d_slave;                /* slave number */
+#define QUES   -1      /* -1 means '?' */
+#define        UNKNOWN -2      /* -2 means not set yet */
+       int     d_dk;                   /* if init 1 set to number for iostat */
+       int     d_flags;                /* flags for device init */
+       char    *d_port;                /* io port base manifest constant */
+       int     d_portn;        /* io port base (if number not manifest) */
+       char    *d_mask;                /* interrupt mask */
+       int     d_maddr;                /* io memory base */
+       int     d_msize;                /* io memory size */
+       int     d_drq;                  /* DMA request */
+       int     d_irq;                  /* interrupt request */
+       int     d_seq;                  /* sequential number */
+       struct  device *d_next;         /* Next one in list */
+};
+#define TO_NEXUS       (struct device *)-1
+#define TO_VBA         (struct device *)-2
+
+struct config {
+       char    *c_dev;
+       char    *s_sysname;
+};
+
+/*
+ * Config has a global notion of which machine type is
+ * being used.  It uses the name of the machine in choosing
+ * files and directories.  Thus if the name of the machine is ``vax'',
+ * it will build from ``Makefile.vax'' and use ``../vax/inline''
+ * in the makerules, etc.
+ */
+int    machine;
+char   *machinename;
+char   *machinearch;
+#define        MACHINE_VAX     1
+#define        MACHINE_TAHOE   2
+#define MACHINE_HP300  3
+#define        MACHINE_I386    4
+#define        MACHINE_PC532   5
+#define        MACHINE_PMAX    6
+#define        MACHINE_AMIGA   7
+
+/*
+ * For each machine, a set of CPU's may be specified as supported.
+ * These and the options (below) are put in the C flags in the makefile.
+ */
+struct cputype {
+       char    *cpu_name;
+       struct  cputype *cpu_next;
+} *cputype;
+
+/*
+ * A set of options may also be specified which are like CPU types,
+ * but which may also specify values for the options.
+ * A separate set of options may be defined for make-style options.
+ */
+struct opt {
+       char    *op_name;
+       char    *op_value;
+       struct  opt *op_next;
+} *opt, *mkopt;
+
+char   *ident;
+char   *ns();
+char   *tc();
+char   *qu();
+char   *get_word();
+char   *get_quoted_word();
+char   *path();
+char   *raisestr();
+
+int    do_trace;
+
+#if MACHINE_VAX
+int    seen_mba, seen_uba;
+#endif
+#if MACHINE_TAHOE
+int    seen_vba;
+#endif
+#if MACHINE_I386
+int    seen_isa;
+#endif
+
+struct device *connect();
+struct device *dtab;
+dev_t  nametodev();
+char   *devtoname();
+
+char   errbuf[80];
+int    yyline;
+
+struct file_list *ftab, *conf_list, **confp, *comp_list, **compp;
+
+int    zone, hadtz;
+int    dst;
+int    profiling;
+int    debugging;
+
+int    maxusers;
+u_int  loadaddress;
+int     fatal_errors;
+
+#define eq(a,b)        (!strcmp(a,b))
diff --git a/usr.sbin/config.old/config.old.8 b/usr.sbin/config.old/config.old.8
new file mode 100644 (file)
index 0000000..4213b62
--- /dev/null
@@ -0,0 +1,173 @@
+.\"    $NetBSD: config.old.8,v 1.9 1995/08/17 17:22:09 thorpej Exp $
+.\"
+.\" Copyright (c) 1980, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     from: @(#)config.8     6.5 (Berkeley) 3/16/91
+.\"
+.Dd March 16, 1991
+.Dt CONFIG.OLD 8
+.Os BSD 4
+.Sh NAME
+.Nm config.old
+.Nd build system configuration files
+.Sh SYNOPSIS
+.Nm config.old
+.Op Fl gkp
+.Ar SYSTEM_NAME
+.Sh DESCRIPTION
+.Pp
+.Nm config.old
+builds a set of system configuration files from the file
+.Ar SYSTEM_NAME
+which describes
+the system to configure.
+A second file
+tells
+.Nm config.old
+what files are needed to generate a system and
+can be augmented by configuration specific set of files
+that give alternate files for a specific machine.
+(see the
+.Sx FILES
+section below)
+.Pp
+Available option and operand:
+.Pp
+.Bl -tag -width SYSTEM_NAME
+.It Fl g
+If the
+.Fl g
+option is supplied, 
+.Nm config.old
+will configure a system for debugging.
+.It Fl k
+If the
+.Fl k
+option is supplied, 
+.Nm config.old
+will not fail immediately on detection of a configuration error.
+.It Fl p
+If the
+.Fl p
+option is supplied, 
+.Nm config.old
+will configure a system for profiling; for example,
+.Xr kgmon 8
+and
+.Xr gprof 1 .
+
+.It Ar SYSTEM_NAME
+specifies the name of the system configuration file
+containing device specifications, configuration options
+and other system parameters for one system configuration.
+.El
+.Pp
+.Nm config.old
+should be run from the
+.Pa conf
+subdirectory of the system source (usually
+.Pa /sys/arch/ARCH/conf ) .
+.Nm Config.old
+assumes the directory
+.Pa ../compile/SYSTEM_NAME
+exists and places all output files there.  
+The output of
+.Nm config.old
+consists of a number of files; for the
+.Tn i386 ,
+they are:
+.Pa ioconf.c ,
+a description
+of what I/O devices are attached to the system;
+.Pa vector.s ,
+a set of interrupt service routines for devices
+attached to the bus plus
+offsets into a structure used for counting per-device interrupts;
+.Pa Makefile ,
+used by
+.Xr make 1
+in building the system;
+header files,
+definitions of
+the number of various devices that will be compiled into the system;
+swap configuration files,
+definitions for
+the disk areas to be used for swapping, the root file system,
+argument processing, and system dumps.
+.Pp
+After running
+.Nm config.old ,
+it is necessary to run
+.Dq Li make depend
+in the directory where the new makefile
+was created.
+.Nm Config.old
+prints a reminder of this when it completes.
+.Pp
+If any other error messages are produced by
+.Nm config.old ,
+the problems in the configuration file should be corrected and
+.Nm config.old
+should be run again.
+Attempts to compile a system that had configuration errors
+are likely to fail.
+.Sh FILES
+.Bl -tag -width /sys/arch/i386/conf/Makefile.i386 -compact
+.It Pa /sys/arch/i386/conf/Makefile.i386
+generic makefile for the
+.Tn i386
+.It Pa /sys/conf/files.oldconf
+list of common files system is built from
+.It Pa /sys/arch/i386/conf/files.i386.oldconf
+list of
+.Tn i386
+specific files
+.It Pa /sys/arch/i386/conf/devices.i386.oldconf
+name to major device mapping file for the
+.Tn i386
+.It Pa /sys/arch/i386/conf/files.oldconf. Ns Em ERNIE
+list of files specific to
+.Em ERNIE
+system
+.El
+.Sh SEE ALSO
+The SYNOPSIS portion of each device in section 4.
+.Rs
+.%T "Building 4.3 BSD UNIX System with Config"
+.Re
+.Sh BUGS
+The line numbers reported in error messages are usually off by one.
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.1 .
diff --git a/usr.sbin/config.old/config.y b/usr.sbin/config.old/config.y
new file mode 100644 (file)
index 0000000..5a9787b
--- /dev/null
@@ -0,0 +1,1102 @@
+%union {
+       char    *str;
+       int     val;
+       struct  file_list *file;
+       struct  idlst *lst;
+}
+
+%token AND
+%token ANY
+%token ARGS
+%token AT
+%token BIO
+%token COMMA
+%token CONFIG
+%token CONTROLLER
+%token CPU
+%token CSR
+%token DEVICE
+%token DISK
+%token DRIVE
+%token DRQ
+%token DST
+%token DUMPS
+%token EQUALS
+%token FLAGS
+%token HIGH
+%token HZ
+%token IDENT
+%token INTERLEAVE
+%token IOMEM
+%token IOSIZ
+%token IRQ
+%token MACHIN
+%token MAJOR
+%token         MANUFACTURER
+%token MASTER
+%token MAXUSERS
+%token MINOR
+%token MINUS
+%token NET
+%token NEXUS
+%token ON
+%token OPTIONS
+%token MAKEOPTIONS
+%token PORT
+%token PRIORITY
+%token         PRODUCT
+%token PSEUDO_DEVICE
+%token ROOT
+%token SEMICOLON
+%token SEQUENTIAL
+%token SIZE
+%token SLAVE
+%token SWAP
+%token TIMEZONE
+%token TTY
+%token TRACE
+%token VECTOR
+
+%token <str>   ID
+%token <val>   NUMBER
+%token <val>   FPNUMBER
+
+%type  <str>   Save_id
+%type  <str>   Opt_value
+%type  <str>   Dev
+%type  <lst>   Id_list
+%type  <val>   optional_size
+%type  <val>   optional_sflag
+%type  <str>   device_name
+%type  <val>   major_minor
+%type  <val>   arg_device_spec
+%type  <val>   root_device_spec
+%type  <val>   dump_device_spec
+%type  <file>  swap_device_spec
+
+%{
+/*     $NetBSD: config.y,v 1.18 1995/08/17 17:22:10 thorpej Exp $      */
+
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from: @(#)config.y      5.14 (Berkeley) 7/1/91
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include "config.h"
+#include "specfile.h"
+
+struct device cur;
+struct device *curp = 0;
+char   *temp_id;
+char   *val_id;
+
+%}
+%%
+Configuration:
+       Many_specs
+               = { verifysystemspecs(); }
+               ;
+
+Many_specs:
+       Many_specs Spec
+               |
+       /* lambda */
+               ;
+
+Spec:
+       Device_spec SEMICOLON
+             = { newdev(&cur); } |
+       Config_spec SEMICOLON
+               |
+       TRACE SEMICOLON
+             = { do_trace = !do_trace; } |
+       SEMICOLON
+               |
+       error SEMICOLON
+               ;
+
+Config_spec:
+       MACHIN Save_id
+           = {
+               if (!strcmp($2, "vax")) {
+                       machine = MACHINE_VAX;
+                       machinename = "vax";
+                       machinearch = machinename;
+               } else if (!strcmp($2, "tahoe")) {
+                       machine = MACHINE_TAHOE;
+                       machinename = "tahoe";
+                       machinearch = machinename;
+               } else if (!strcmp($2, "hp300")) {
+                       machine = MACHINE_HP300;
+                       machinename = "hp300";
+                       machinearch = "m68k";
+               } else if (!strcmp($2, "i386")) {
+                       machine = MACHINE_I386;
+                       machinename = "i386";
+                       machinearch = machinename;
+               } else if (!strcmp($2, "pc532")) {
+                       machine = MACHINE_PC532;
+                       machinename = "pc532";
+                       machinearch = machinename;
+               } else if (!strcmp($2, "pmax")) {
+                       machine = MACHINE_PMAX;
+                       machinename = "pmax";
+                       machinearch = machinename;
+               } else if (!strcmp($2, "amiga")) {
+                       machine = MACHINE_AMIGA;
+                       machinename = "amiga";
+                       machinearch = "m68k";
+               } else
+                       yyerror("Unknown machine type");
+             } |
+       CPU Save_id
+             = {
+               struct cputype *cp =
+                   (struct cputype *)malloc(sizeof (struct cputype));
+               cp->cpu_name = ns($2);
+               cp->cpu_next = cputype;
+               cputype = cp;
+               free(temp_id);
+             } |
+       OPTIONS Opt_list
+               |
+       MAKEOPTIONS Mkopt_list
+               |
+       IDENT ID
+             = { ident = ns($2); } |
+       System_spec
+               |
+       HZ NUMBER
+             = { yyerror("HZ specification obsolete; delete"); } |
+       TIMEZONE NUMBER
+             = { zone = 60 * $2; check_tz(); } |
+       TIMEZONE NUMBER DST NUMBER
+             = { zone = 60 * $2; dst = $4; check_tz(); } |
+       TIMEZONE NUMBER DST
+             = { zone = 60 * $2; dst = 1; check_tz(); } |
+       TIMEZONE FPNUMBER
+             = { zone = $2; check_tz(); } |
+       TIMEZONE FPNUMBER DST NUMBER
+             = { zone = $2; dst = $4; check_tz(); } |
+       TIMEZONE FPNUMBER DST
+             = { zone = $2; dst = 1; check_tz(); } |
+       TIMEZONE MINUS NUMBER
+             = { zone = -60 * $3; check_tz(); } |
+       TIMEZONE MINUS NUMBER DST NUMBER
+             = { zone = -60 * $3; dst = $5; check_tz(); } |
+       TIMEZONE MINUS NUMBER DST
+             = { zone = -60 * $3; dst = 1; check_tz(); } |
+       TIMEZONE MINUS FPNUMBER
+             = { zone = -$3; check_tz(); } |
+       TIMEZONE MINUS FPNUMBER DST NUMBER
+             = { zone = -$3; dst = $5; check_tz(); } |
+       TIMEZONE MINUS FPNUMBER DST
+             = { zone = -$3; dst = 1; check_tz(); } |
+       MAXUSERS NUMBER
+             = { maxusers = $2; };
+
+System_spec:
+         System_id System_parameter_list
+               = { checksystemspec(*confp); }
+       ;
+               
+System_id:
+         CONFIG Save_id
+               = { mkconf($2); }
+       ;
+
+System_parameter_list:
+         System_parameter_list System_parameter
+       | System_parameter
+       ;
+
+System_parameter:
+         addr_spec
+       | swap_spec
+       | root_spec
+       | dump_spec
+       | arg_spec
+       ;
+       
+addr_spec:
+         AT NUMBER
+               = { loadaddress = $2; };
+       ;
+
+swap_spec:
+         SWAP optional_on swap_device_list
+       ;
+       
+swap_device_list:
+         swap_device_list AND swap_device
+       | swap_device
+       ;
+       
+swap_device:
+         swap_device_spec optional_size optional_sflag
+             = { mkswap(*confp, $1, $2, $3); }
+       ;
+
+swap_device_spec:
+         device_name
+               = {
+                       struct file_list *fl = newswap();
+
+                       if (eq($1, "generic") || eq($1, "nfs"))
+                               fl->f_fn = $1;
+                       else {
+                               fl->f_swapdev = nametodev($1, 0, 'b');
+                               fl->f_fn = devtoname(fl->f_swapdev);
+                       }
+                       $$ = fl;
+               }
+       | major_minor
+               = {
+                       struct file_list *fl = newswap();
+
+                       fl->f_swapdev = $1;
+                       fl->f_fn = devtoname($1);
+                       $$ = fl;
+               }
+       ;
+
+root_spec:
+         ROOT optional_on root_device_spec
+               = {
+                       struct file_list *fl = *confp;
+
+                       if (fl && fl->f_rootdev != NODEV)
+                               yyerror("extraneous root device specification");
+                       else
+                               fl->f_rootdev = $3;
+               }
+       ;
+
+root_device_spec:
+         device_name
+               = { $$ = nametodev($1, 0, 'a'); }
+       | major_minor
+       ;
+
+dump_spec:
+         DUMPS optional_on dump_device_spec
+               = {
+                       struct file_list *fl = *confp;
+
+                       if (fl && fl->f_dumpdev != NODEV)
+                               yyerror("extraneous dump device specification");
+                       else
+                               fl->f_dumpdev = $3;
+               }
+
+       ;
+
+dump_device_spec:
+         device_name
+               = { $$ = nametodev($1, 0, 'b'); }
+       | major_minor
+       ;
+
+arg_spec:
+         ARGS optional_on arg_device_spec
+               = { yyerror("arg device specification obsolete, ignored"); }
+       ;
+
+arg_device_spec:
+         device_name
+               = { $$ = nametodev($1, 0, 'b'); }
+       | major_minor
+       ;
+
+major_minor:
+         MAJOR NUMBER MINOR NUMBER
+               = { $$ = makedev($2, $4); }
+       ;
+
+optional_on:
+         ON
+       | /* empty */
+       ;
+
+optional_size:
+         SIZE NUMBER
+             = { $$ = $2; }
+       | /* empty */
+             = { $$ = 0; }
+       ;
+
+optional_sflag:
+         SEQUENTIAL
+             = { $$ = 2; }
+       | /* empty */
+             = { $$ = 0; }
+       ;
+
+device_name:
+         Save_id
+               = { $$ = $1; }
+       | Save_id NUMBER
+               = {
+                       char buf[80];
+
+                       (void) sprintf(buf, "%s%d", $1, $2);
+                       $$ = ns(buf); free($1);
+               }
+       | Save_id NUMBER ID
+               = {
+                       char buf[80];
+
+                       (void) sprintf(buf, "%s%d%s", $1, $2, $3);
+                       $$ = ns(buf); free($1);
+               }
+       ;
+
+Opt_list:
+       Opt_list COMMA Option
+               |
+       Option
+               ;
+
+Option:
+       Save_id
+             = {
+               struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+               op->op_name = ns($1);
+               op->op_next = opt;
+               op->op_value = 0;
+               opt = op;
+               free(temp_id);
+             } |
+       Save_id EQUALS Opt_value
+             = {
+               struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+               op->op_name = ns($1);
+               op->op_next = opt;
+               op->op_value = ns($3);
+               opt = op;
+               free(temp_id);
+               free(val_id);
+             } ;
+
+Opt_value:
+       ID
+             = { $$ = val_id = ns($1); } |
+       NUMBER
+             = {
+               char nb[16];
+               (void) sprintf(nb, "%d", $1);
+               $$ = val_id = ns(nb);
+             } ;
+
+
+Save_id:
+       ID
+             = { $$ = temp_id = ns($1); }
+       ;
+
+Mkopt_list:
+       Mkopt_list COMMA Mkoption
+               |
+       Mkoption
+               ;
+
+Mkoption:
+       Save_id EQUALS Opt_value
+             = {
+               struct opt *op = (struct opt *)malloc(sizeof (struct opt));
+               op->op_name = ns($1);
+               op->op_next = mkopt;
+               op->op_value = ns($3);
+               mkopt = op;
+               free(temp_id);
+               free(val_id);
+             } ;
+
+Dev:
+       ID
+             = { $$ = ns($1); }
+       ;
+
+Device_spec:
+       DEVICE Dev_name Dev_info Int_spec
+             = { cur.d_type = DEVICE; } |
+       MASTER Dev_name Dev_info Int_spec
+             = { cur.d_type = MASTER; } |
+       DISK Dev_name Dev_info Int_spec
+             = { cur.d_dk = 1; cur.d_type = DEVICE; } |
+       CONTROLLER Dev_name Dev_info Int_spec
+             = { cur.d_type = CONTROLLER; } |
+       PSEUDO_DEVICE Init_dev Dev
+             = {
+               cur.d_name = $3;
+               cur.d_type = PSEUDO_DEVICE;
+               } |
+       PSEUDO_DEVICE Init_dev Dev NUMBER
+             = {
+               cur.d_name = $3;
+               cur.d_type = PSEUDO_DEVICE;
+               cur.d_slave = $4;
+               };
+
+Dev_name:
+       Init_dev Dev NUMBER
+             = {
+               cur.d_name = $2;
+               if (eq($2, "mba"))
+                       seen_mba = 1;
+               else if (eq($2, "uba"))
+                       seen_uba = 1;
+               else if (eq($2, "vba"))
+                       seen_vba = 1;
+               else if (eq($2, "isa"))
+                       seen_isa = 1;
+               cur.d_unit = $3;
+               };
+
+Init_dev:
+       /* lambda */
+             = { init_dev(&cur); };
+
+Dev_info:
+       Con_info Info_list
+               |
+       /* lambda */
+               ;
+
+Con_info:
+       AT Dev NUMBER
+             = {
+               if (eq(cur.d_name, "mba") || eq(cur.d_name, "uba")) {
+                       (void) sprintf(errbuf,
+                               "%s must be connected to a nexus", cur.d_name);
+                       yyerror(errbuf);
+               }
+               cur.d_conn = connect($2, $3);
+               } |
+       AT NEXUS NUMBER
+             = { check_nexus(&cur, $3); cur.d_conn = TO_NEXUS; } |
+        AT MANUFACTURER NUMBER PRODUCT NUMBER
+              = { check_manuf_prod (&cur, $3, $5); cur.d_conn = TO_NEXUS; } ;
+
+Info_list:
+       Info_list Info
+               |
+       /* lambda */
+               ;
+
+Info:
+       CSR NUMBER
+             = { cur.d_addr = $2; } |
+       DRIVE NUMBER
+             = { cur.d_drive = $2; } |
+       SLAVE NUMBER
+             = {
+               if (cur.d_conn != 0 && cur.d_conn != TO_NEXUS &&
+                   cur.d_conn->d_type == MASTER)
+                       cur.d_slave = $2;
+               else
+                       yyerror("can't specify slave--not to master");
+               } |
+       IRQ NUMBER
+             = { cur.d_irq = $2; } |
+       DRQ NUMBER
+             = { cur.d_drq = $2; } |
+       IOMEM NUMBER
+             = { cur.d_maddr = $2; } |
+       IOSIZ NUMBER
+             = { cur.d_msize = $2; } |
+       PORT device_name
+             = { cur.d_port = ns($2); } |
+       PORT NUMBER
+             = { cur.d_portn = $2; } |
+       TTY 
+             = { cur.d_mask = "tty"; } |
+       BIO 
+             = { cur.d_mask = "bio"; } |
+       NET 
+             = { cur.d_mask = "net"; } |
+       HIGH
+             = { cur.d_mask = "high"; } |
+       FLAGS NUMBER
+             = { cur.d_flags = $2; };
+
+Int_spec:
+       VECTOR Id_list
+             = { cur.d_vec = $2; } |
+       PRIORITY NUMBER
+             = { cur.d_pri = $2; } |
+       /* lambda */
+               ;
+
+Id_list:
+       Save_id
+             = {
+               struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
+               a->id = $1; a->id_next = 0; $$ = a;
+               } |
+       Save_id Id_list =
+               {
+               struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst));
+               a->id = $1; a->id_next = $2; $$ = a;
+               };
+
+%%
+
+yyerror(s)
+       char *s;
+{
+
+       fprintf(stderr, "config.old: line %d: %s\n", yyline + 1, s);
+}
+
+/*
+ * return the passed string in a new space
+ */
+char *
+ns(str)
+       register char *str;
+{
+       register char *cp;
+
+       cp = malloc((unsigned)(strlen(str)+1));
+       (void) strcpy(cp, str);
+       return (cp);
+}
+
+/*
+ * add a device to the list of devices
+ */
+newdev(dp)
+       register struct device *dp;
+{
+       register struct device *np;
+
+       np = (struct device *) malloc(sizeof *np);
+       *np = *dp;
+       np->d_next = 0;
+       if (curp == 0)
+               dtab = np;
+       else
+               curp->d_next = np;
+       curp = np;
+}
+
+/*
+ * note that a configuration should be made
+ */
+mkconf(sysname)
+       char *sysname;
+{
+       register struct file_list *fl, **flp;
+       register struct name_expr *expr;
+
+       fl = (struct file_list *) malloc(sizeof *fl);
+       expr = (struct name_expr *) malloc(sizeof *expr);
+       fl->f_type = SYSTEMSPEC;
+       fl->f_needs = expr;
+       expr->type = T_IDENTIFIER;
+       expr->name = sysname;
+       fl->f_rootdev = NODEV;
+       fl->f_dumpdev = NODEV;
+       fl->f_fn = 0;
+       fl->f_next = 0;
+       for (flp = confp; *flp; flp = &(*flp)->f_next)
+               ;
+       *flp = fl;
+       confp = flp;
+}
+
+struct file_list *
+newflist(ftype)
+       u_char ftype;
+{
+       struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
+
+       fl->f_type = ftype;
+       fl->f_next = 0;
+       fl->f_swapdev = NODEV;
+       fl->f_swapsize = 0;
+       fl->f_needs = 0;
+       fl->f_fn = 0;
+       return (fl);
+}
+
+struct file_list *
+newswap()
+{
+       struct file_list *fl = (struct file_list *)malloc(sizeof (*fl));
+
+       fl->f_type = SWAPSPEC;
+       fl->f_next = 0;
+       fl->f_swapdev = NODEV;
+       fl->f_swapsize = 0;
+       fl->f_needs = 0;
+       fl->f_fn = 0;
+       return (fl);
+}
+
+/*
+ * Add a swap device to the system's configuration
+ */
+mkswap(system, fl, size)
+       struct file_list *system, *fl;
+       int size;
+{
+       register struct file_list **flp;
+       char name[80];
+
+       if (system == 0 || system->f_type != SYSTEMSPEC) {
+               yyerror("\"swap\" spec precedes \"config\" specification");
+               return;
+       }
+       if (size < 0) {
+               yyerror("illegal swap partition size");
+               return;
+       }
+       /*
+        * Append swap description to the end of the list.
+        */
+       flp = &system->f_next;
+       for (; *flp && (*flp)->f_type == SWAPSPEC; flp = &(*flp)->f_next)
+               ;
+       fl->f_next = *flp;
+       *flp = fl;
+       fl->f_swapsize = size;
+       /*
+        * If first swap device for this system,
+        * set up f_fn field to insure swap
+        * files are created with unique names.
+        */
+       if (system->f_fn)
+               return;
+       if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs"))
+               system->f_fn = ns(fl->f_fn);
+       else
+               system->f_fn = ns(system->f_needs->name);
+}
+
+mkcomp(dp)
+       register struct device *dp;
+{
+       register struct file_list *fl, **flp;
+       register struct name_expr *expr;
+       char buf[80];
+
+       fl = (struct file_list *) malloc(sizeof *fl);
+       expr = (struct name_expr *) malloc(sizeof *expr);
+
+       fl->f_needs = expr;
+       expr->type = T_DEVICE_DRIVER;
+
+       fl->f_type = COMPDEVICE;
+       fl->f_compinfo = dp->d_unit;
+       fl->f_fn = ns(dp->d_name);
+       (void) sprintf(buf, "%s%d", dp->d_name, dp->d_unit);
+       fl->f_needs->name = ns(buf);
+       fl->f_next = 0;
+       for (flp = compp; *flp; flp = &(*flp)->f_next)
+               ;
+       *flp = fl;
+       compp = flp;
+}
+
+addcomp(compdev, fl)
+       struct file_list *compdev, *fl;
+{
+       register struct file_list **flp;
+       char name[80];
+
+       if (compdev == 0 || compdev->f_type != COMPDEVICE) {
+               yyerror("component spec precedes device specification");
+               return;
+       }
+       /*
+        * Append description to the end of the list.
+        */
+       flp = &compdev->f_next;
+       for (; *flp && (*flp)->f_type == COMPSPEC; flp = &(*flp)->f_next)
+               ;
+       fl->f_next = *flp;
+       *flp = fl;
+}
+
+/*
+ * find the pointer to connect to the given device and number.
+ * returns 0 if no such device and prints an error message
+ */
+struct device *
+connect(dev, num)
+       register char *dev;
+       register int num;
+{
+       register struct device *dp;
+       struct device *huhcon();
+
+       if (num == QUES)
+               return (huhcon(dev));
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               if ((num != dp->d_unit) || !eq(dev, dp->d_name))
+                       continue;
+               if (dp->d_type != CONTROLLER && dp->d_type != MASTER) {
+                       (void) sprintf(errbuf,
+                           "%s connected to non-controller", dev);
+                       yyerror(errbuf);
+                       return (0);
+               }
+               return (dp);
+       }
+       (void) sprintf(errbuf, "%s %d not defined", dev, num);
+       yyerror(errbuf);
+       return (0);
+}
+
+/*
+ * connect to an unspecific thing
+ */
+struct device *
+huhcon(dev)
+       register char *dev;
+{
+       register struct device *dp, *dcp;
+       struct device rdev;
+       int oldtype;
+
+       /*
+        * First make certain that there are some of these to wildcard on
+        */
+       for (dp = dtab; dp != 0; dp = dp->d_next)
+               if (eq(dp->d_name, dev))
+                       break;
+       if (dp == 0) {
+               (void) sprintf(errbuf, "no %s's to wildcard", dev);
+               yyerror(errbuf);
+               return (0);
+       }
+       oldtype = dp->d_type;
+       dcp = dp->d_conn;
+       /*
+        * Now see if there is already a wildcard entry for this device
+        * (e.g. Search for a "uba ?")
+        */
+       for (; dp != 0; dp = dp->d_next)
+               if (eq(dev, dp->d_name) && dp->d_unit == -1)
+                       break;
+       /*
+        * If there isn't, make one because everything needs to be connected
+        * to something.
+        */
+       if (dp == 0) {
+               dp = &rdev;
+               init_dev(dp);
+               dp->d_unit = QUES;
+               dp->d_name = ns(dev);
+               dp->d_type = oldtype;
+               newdev(dp);
+               dp = curp;
+               /*
+                * Connect it to the same thing that other similar things are
+                * connected to, but make sure it is a wildcard unit
+                * (e.g. up connected to sc ?, here we make connect sc? to a
+                * uba?).  If other things like this are on the NEXUS or
+                * if they aren't connected to anything, then make the same
+                * connection, else call ourself to connect to another
+                * unspecific device.
+                */
+               if (dcp == TO_NEXUS || dcp == 0)
+                       dp->d_conn = dcp;
+               else
+                       dp->d_conn = connect(dcp->d_name, QUES);
+       }
+       return (dp);
+}
+
+init_dev(dp)
+       register struct device *dp;
+{
+
+       dp->d_name = "OHNO!!!";
+       dp->d_type = DEVICE;
+       dp->d_conn = 0;
+       dp->d_vec = 0;
+       dp->d_addr = dp->d_pri = dp->d_flags = dp->d_dk = 0;
+       dp->d_slave = dp->d_drive = dp->d_unit = UNKNOWN;
+       dp->d_port = (char *)0;
+       dp->d_portn = 0;
+       dp->d_irq = -2;
+       dp->d_drq = -1;
+       dp->d_maddr = 0;
+       dp->d_msize = 0;
+       dp->d_mask = "null";
+}
+
+/*
+ * make certain that this is a reasonable type of thing to connect to a nexus
+ */
+check_nexus(dev, num)
+       register struct device *dev;
+       int num;
+{
+
+       switch (machine) {
+
+       case MACHINE_VAX:
+               if (!eq(dev->d_name, "uba") && !eq(dev->d_name, "mba") &&
+                   !eq(dev->d_name, "bi"))
+                       yyerror("only uba's, mba's, and bi's should be connected to the nexus");
+               if (num != QUES)
+                       yyerror("can't give specific nexus numbers");
+               break;
+
+       case MACHINE_TAHOE:
+               if (!eq(dev->d_name, "vba")) 
+                       yyerror("only vba's should be connected to the nexus");
+               break;
+
+       case MACHINE_HP300:
+               if (num != QUES)
+                       dev->d_addr = num;
+               break;
+
+       case MACHINE_I386:
+               if (!eq(dev->d_name, "isa"))
+                       yyerror("only isa's should be connected to the nexus");
+               break;
+       }
+}
+
+/*
+ * build a nexus ID out of manufacturer and product code
+ */
+check_manuf_prod (dev, manuf, prod)
+       register struct device *dev;
+       int manuf, prod;
+{
+       /* need either both wildcard or none */
+       if ((manuf == QUES) != (prod == QUES))
+               yyerror ("manufacturer and product must either be both set or both wildcard.");
+
+       /* enough to check one now */
+       if (manuf != QUES)
+               dev->d_addr = ((manuf & 0xffff) << 16) | (prod & 0xffff);
+}
+
+/*
+ * Check the timezone to make certain it is sensible
+ */
+
+check_tz()
+{
+       if (abs(zone) > 12 * 60)
+               yyerror("timezone is unreasonable");
+       else
+               hadtz = 1;
+}
+
+/*
+ * Check system specification and apply defaulting
+ * rules on root, argument, dump, and swap devices.
+ */
+checksystemspec(fl)
+       register struct file_list *fl;
+{
+       char buf[BUFSIZ];
+       register struct file_list *swap;
+       int generic, nfs;
+
+       if (fl == 0 || fl->f_type != SYSTEMSPEC) {
+               yyerror("internal error, bad system specification");
+               exit(1);
+       }
+       swap = fl->f_next;
+       generic = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "generic");
+       nfs = swap && swap->f_type == SWAPSPEC && eq(swap->f_fn, "nfs");
+       if (fl->f_rootdev == NODEV && !generic && !nfs) {
+               yyerror("no root device specified");
+               exit(1);
+       }
+       /*
+        * Default swap area to be in 'b' partition of root's
+        * device.  If root specified to be other than on 'a'
+        * partition, give warning, something probably amiss.
+        */
+       if (swap == 0 || swap->f_type != SWAPSPEC) {
+               dev_t dev;
+
+               swap = newswap();
+               dev = fl->f_rootdev;
+               if (minor(dev) & 07) {
+                       (void) sprintf(buf, 
+"Warning, swap defaulted to 'b' partition with root on '%c' partition",
+                               (minor(dev) & 07) + 'a');
+                       yyerror(buf);
+               }
+               swap->f_swapdev =
+                  makedev(major(dev), (minor(dev) &~ 07) | ('b' - 'a'));
+               swap->f_fn = devtoname(swap->f_swapdev);
+               mkswap(fl, swap, 0);
+       }
+       /*
+        * Make sure a generic swap isn't specified, along with
+        * other stuff (user must really be confused).
+        */
+       if (generic) {
+               if (fl->f_rootdev != NODEV)
+                       yyerror("root device specified with generic swap");
+               if (fl->f_dumpdev != NODEV)
+                       yyerror("dump device specified with generic swap");
+               return;
+       }
+       /*
+        * Default dump device and warn if place is not a
+        * swap area.
+        */
+       if (fl->f_dumpdev == NODEV)
+               fl->f_dumpdev = swap->f_swapdev;
+       if (fl->f_dumpdev != swap->f_swapdev) {
+               struct file_list *p = swap->f_next;
+
+               for (; p && p->f_type == SWAPSPEC; p = p->f_next)
+                       if (fl->f_dumpdev == p->f_swapdev)
+                               return;
+               (void) sprintf(buf,
+                   "Warning: dump device is not a swap partition");
+               yyerror(buf);
+       }
+}
+
+/*
+ * Verify all devices specified in the system specification
+ * are present in the device specifications.
+ */
+verifysystemspecs()
+{
+       register struct file_list *fl;
+       dev_t checked[50], *verifyswap();
+       register dev_t *pchecked = checked;
+
+       for (fl = conf_list; fl; fl = fl->f_next) {
+               if (fl->f_type != SYSTEMSPEC)
+                       continue;
+               if (!finddev(fl->f_rootdev))
+                       deverror(fl->f_needs->name, "root");
+               *pchecked++ = fl->f_rootdev;
+               pchecked = verifyswap(fl->f_next, checked, pchecked);
+#define        samedev(dev1, dev2) \
+       ((minor(dev1) &~ 07) != (minor(dev2) &~ 07))
+               if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) {
+                       if (!finddev(fl->f_dumpdev))
+                               deverror(fl->f_needs->name, "dump");
+                       *pchecked++ = fl->f_dumpdev;
+               }
+       }
+}
+
+/*
+ * Do as above, but for swap devices.
+ */
+dev_t *
+verifyswap(fl, checked, pchecked)
+       register struct file_list *fl;
+       dev_t checked[];
+       register dev_t *pchecked;
+{
+
+       for (;fl && fl->f_type == SWAPSPEC; fl = fl->f_next) {
+               if (eq(fl->f_fn, "generic") || eq(fl->f_fn,"nfs"))
+                       continue;
+               if (alreadychecked(fl->f_swapdev, checked, pchecked))
+                       continue;
+               if (!finddev(fl->f_swapdev))
+                       fprintf(stderr,
+                          "config.old: swap device %s not configured", fl->f_fn);
+               *pchecked++ = fl->f_swapdev;
+       }
+       return (pchecked);
+}
+
+/*
+ * Verify that components of a compound device have themselves been config'ed
+ */
+verifycomp(fl)
+       register struct file_list *fl;
+{
+       char *dname = fl->f_needs->name;
+
+       for (fl = fl->f_next; fl; fl = fl->f_next) {
+               if (fl->f_type != COMPSPEC || finddev(fl->f_compdev))
+                       continue;
+               fprintf(stderr,
+                       "config.old: %s: component device %s not configured\n",
+                       dname, fl->f_needs->name);
+       }
+}
+
+/*
+ * Has a device already been checked
+ * for it's existence in the configuration?
+ */
+alreadychecked(dev, list, last)
+       dev_t dev, list[];
+       register dev_t *last;
+{
+       register dev_t *p;
+
+       for (p = list; p < last; p++)
+               if (samedev(*p, dev))
+                       return (1);
+       return (0);
+}
+
+deverror(systemname, devtype)
+       char *systemname, *devtype;
+{
+
+       fprintf(stderr, "config.old: %s: %s device not configured\n",
+               systemname, devtype);
+}
+
+/*
+ * Look for the device in the list of
+ * configured hardware devices.  Must
+ * take into account stuff wildcarded.
+ */
+/*ARGSUSED*/
+finddev(dev)
+       dev_t dev;
+{
+
+       /* punt on this right now */
+       return (1);
+}
diff --git a/usr.sbin/config.old/lang.l b/usr.sbin/config.old/lang.l
new file mode 100644 (file)
index 0000000..cc3eaf2
--- /dev/null
@@ -0,0 +1,227 @@
+%{
+/*     $NetBSD: lang.l,v 1.12 1995/08/17 17:22:11 thorpej Exp $        */
+
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from: @(#)lang.l        5.8 (Berkeley) 4/19/91
+ */
+
+#include <ctype.h>
+#include "y.tab.h"
+#include "config.h"
+
+#define tprintf if (do_trace) printf
+
+/*
+ * Key word table
+ */
+
+struct kt {
+       char *kt_name;
+       int kt_val;
+} key_words[] = {
+       { "and",        AND },
+       { "args",       ARGS },
+       { "at",         AT },
+#if MACHINE_I386
+       { "bio",        BIO },
+#endif MACHINE_I386
+       { "config",     CONFIG },
+       { "controller", CONTROLLER },
+       { "cpu",        CPU },
+       { "csr",        CSR },
+       { "device",     DEVICE },
+       { "disk",       DISK },
+       { "drive",      DRIVE },
+#if MACHINE_I386
+       { "drq",        DRQ },
+#endif MACHINE_I386
+       { "dst",        DST },
+       { "dumps",      DUMPS },
+       { "flags",      FLAGS },
+#if MACHINE_I386
+       { "high",       HIGH },
+#endif MACHINE_I386
+       { "hz",         HZ },
+       { "ident",      IDENT },
+       { "interleave", INTERLEAVE },
+#if MACHINE_I386
+       { "iomem",      IOMEM },
+       { "iosiz",      IOSIZ },
+       { "irq",        IRQ },
+#endif MACHINE_I386
+       { "machine",    MACHIN },
+       { "major",      MAJOR },
+       { "makeoptions", MAKEOPTIONS },
+#if MACHINE_AMIGA
+        { "manufacturer", MANUFACTURER },
+#endif
+       { "master",     MASTER },
+       { "maxusers",   MAXUSERS },
+       { "minor",      MINOR },
+#if MACHINE_I386
+       { "net",        NET },
+#endif MACHINE_I386
+       { "nexus",      NEXUS },
+       { "on",         ON },
+       { "options",    OPTIONS },
+#if MACHINE_I386
+       { "port",       PORT },
+#endif MACHINE_I386
+       { "priority",   PRIORITY },
+#if MACHINE_AMIGA
+        { "product",    PRODUCT },
+#endif
+       { "pseudo-device",PSEUDO_DEVICE },
+       { "root",       ROOT },
+       { "sequential", SEQUENTIAL },
+#if MACHINE_HP300
+       { "scode",      NEXUS },
+#endif
+       { "size",       SIZE },
+       { "slave",      SLAVE },
+       { "swap",       SWAP },
+       { "tape",       DEVICE },
+#if MACHINE_I386
+       { "tty",        TTY },
+#endif MACHINE_I386
+       { "timezone",   TIMEZONE },
+       { "trace",      TRACE },
+       { "vector",     VECTOR },
+       { 0, 0 },
+};
+%}
+WORD  [A-Za-z_]([A-Za-z_0-9]+[A-Za-z_])*[-A-Za-z_]*
+%%
+{WORD}         {
+                       int i;
+
+                       if ((i = kw_lookup(yytext)) == -1)
+                       {
+                               yylval.str = yytext;
+                               tprintf("id(%s) ", yytext);
+                               return ID;
+                       }
+                       tprintf("(%s) ", yytext);
+                       return i;
+               }
+\"([^\"]|\\\")*\"      {
+                       yytext[strlen(yytext)-1] = '\0';
+                       yylval.str = yytext + 1;
+                       tprintf("QID: %s", yylval.str);
+                       return ID;
+               }
+0[0-7]*                {
+                       yylval.val = octal(yytext);
+                       tprintf("#O:%o ", yylval.val);
+                       return NUMBER;
+               }
+0x[0-9a-fA-F]+ {
+                       yylval.val = hex(yytext);
+                       tprintf("#X:%x ", yylval.val);
+                       return NUMBER;
+               }
+[1-9][0-9]*    {
+                       yylval.val = atoi(yytext);
+                       tprintf("#D:%d ", yylval.val);
+                       return NUMBER;
+               }
+[0-9]"."[0-9]* {
+                       double atof();
+                       yylval.val = (int) (60 * atof(yytext) + 0.5);
+                       return FPNUMBER;
+               }
+"-"            {
+                       return MINUS;
+               }
+"?"            {
+                       yylval.val = -1;
+                       tprintf("? ");
+                       return NUMBER;
+               }
+\n/[ \t]       {
+                       yyline++;
+                       tprintf("\n... ");
+               }
+\n             {
+                       yyline++;
+                       tprintf("\n");
+                       return SEMICOLON;
+               }
+#.*            {       /* Ignored (comment) */;        }
+[ \t]*         {       /* Ignored (white space) */;    }
+";"            {       return SEMICOLON;               }
+","            {       return COMMA;                   }
+"="            {       return EQUALS;                  }
+"@"            {       return AT;                      }
+.              {       return yytext[0];               }
+
+%%
+/*
+ * kw_lookup
+ *     Look up a string in the keyword table.  Returns a -1 if the
+ *     string is not a keyword otherwise it returns the keyword number
+ */
+
+kw_lookup(word)
+register char *word;
+{
+       register struct kt *kp;
+
+       for (kp = key_words; kp->kt_name != 0; kp++)
+               if (eq(word, kp->kt_name))
+                       return kp->kt_val;
+       return -1;
+}
+
+/*
+ * Number conversion routines
+ */
+
+octal(str)
+char *str;
+{
+       int num;
+
+       (void) sscanf(str, "%o", &num);
+       return num;
+}
+
+hex(str)
+char *str;
+{
+       int num;
+
+       (void) sscanf(str+2, "%x", &num);
+       return num;
+}
diff --git a/usr.sbin/config.old/main.c b/usr.sbin/config.old/main.c
new file mode 100644 (file)
index 0000000..1ffb3da
--- /dev/null
@@ -0,0 +1,338 @@
+/*     $NetBSD: main.c,v 1.13 1995/08/17 17:22:12 thorpej Exp $        */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)main.c     5.17 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: main.c,v 1.13 1995/08/17 17:22:12 thorpej Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "y.tab.h"
+#include "config.h"
+
+static char *PREFIX;
+
+/*
+ * Config builds a set of files for building a UNIX
+ * system given a description of the desired system.
+ */
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+
+       extern char *optarg;
+       extern int optind;
+       struct stat buf;
+       int ch;
+       char *p;
+
+       fatal_errors =1;
+       while ((ch = getopt(argc, argv, "gpk")) != EOF)
+               switch (ch) {
+               case 'g':
+                       debugging++;
+                       break;
+               case 'p':
+                       profiling++;
+                       break;
+               case 'k':
+                       fatal_errors=0;
+                       break;
+               case '?':
+               default:
+                       goto usage;
+               }
+       argc -= optind;
+       argv += optind;
+
+       if (argc != 1) {
+usage:         fputs("usage: config.old [-gkp] sysname\n", stderr);
+               exit(1);
+       }
+
+       if (freopen(PREFIX = *argv, "r", stdin) == NULL) {
+               perror(PREFIX);
+               exit(2);
+       }
+       if (stat(p = path((char *)NULL), &buf)) {
+               if (mkdir(p, 0777)) {
+                       perror(p);
+                       exit(2);
+               }
+       }
+       else if ((buf.st_mode & S_IFMT) != S_IFDIR) {
+               fprintf(stderr, "config.old: %s isn't a directory.\n", p);
+               exit(2);
+       }
+
+       loadaddress = -1;
+       dtab = NULL;
+       confp = &conf_list;
+       compp = &comp_list;
+       if (yyparse())
+               exit(3);
+       switch (machine) {
+
+       case MACHINE_VAX:
+               vax_ioconf();           /* Print ioconf.c */
+               ubglue();               /* Create ubglue.s */
+               break;
+
+       case MACHINE_TAHOE:
+               tahoe_ioconf();
+               vbglue();
+               break;
+
+       case MACHINE_HP300:
+               hp300_ioconf();
+               hpglue();
+               break;
+
+       case MACHINE_I386:
+               i386_ioconf();          /* Print ioconf.c */
+               i386_vector();          /* Create vector.s */
+               break;
+
+       case MACHINE_PC532:
+               pc532_ioconf();         /* Print ioconf.c */
+               break;
+
+       case MACHINE_PMAX:
+               pmax_ioconf();
+               break;
+
+        case MACHINE_AMIGA:
+                amiga_ioconf();
+                amigaglue();
+                break;
+  
+       default:
+               printf("Specify machine type, e.g. ``machine vax''\n");
+               exit(1);
+       }
+       /*
+        * make symbolic links in compilation directory
+        * for "sys" (to make genassym.c work along with #include <sys/xxx>)
+        * and similarly for "machine".
+        */
+       {
+       char xxx[200];
+
+#ifndef NO_SYMLINK
+       (void) sprintf(xxx, "../../include");
+       (void) symlink(xxx, path("machine"));
+       (void) sprintf(xxx, "../../../%s/include", machinearch);
+       (void) symlink(xxx, path(machinearch));
+#else
+       sprintf  (xxx, "/bin/rm -rf %s; /bin/cp -r ../include %s",
+                path("machine"), path("machine"));
+       system (xxx);
+       sprintf  (xxx, "/bin/rm -rf %s; /bin/cp -r ../../%s/include %s",
+                path(machinearch), machinearch, path(machinearch));
+       system (xxx);
+#endif
+       }
+       makefile();                     /* build Makefile */
+       headers();                      /* make a lot of .h files */
+       swapconf();                     /* swap config files */
+       printf("Don't forget to run \"make depend\"\n");
+       exit(0);
+}
+
+#define is_paren(x) ((x == '(') || (x == ')'))
+#define is_comment(x) (x == '#')
+/*
+ * get_word
+ *     returns EOF on end of file
+ *     NULL on end of line
+ *     pointer to the word otherwise
+ */
+char *
+get_word(fp)
+       register FILE *fp;
+{
+       static char line[80];
+       register int ch;
+       register char *cp;
+
+       while ((ch = getc(fp)) != EOF)
+               if (ch != ' ' && ch != '\t')
+                       break;
+       if (ch == EOF)
+               return ((char *)EOF);
+       if (ch == '\n')
+               return (NULL);
+       if (is_paren(ch)) {
+           line[0] = ch;
+           line[1] = '\0';
+           return line;
+       }
+       if (is_comment(ch)) {
+           while ((ch = getc(fp)) != EOF)
+               if (ch == '\n')
+                   break;
+           if (ch == EOF) return ((char *)EOF);
+           else return NULL;
+       }
+       cp = line;
+       *cp++ = ch;
+       while ((ch = getc(fp)) != EOF) {
+           if (isspace(ch) || is_paren(ch))
+                       break;
+               *cp++ = ch;
+       }
+       *cp = 0;
+       if (ch == EOF)
+               return ((char *)EOF);
+       (void) ungetc(ch, fp);
+       return (line);
+}
+
+/*
+ * get_rword
+ *     returns EOF on end of file
+ *     NULL on end of line
+ *     pointer to the word otherwise
+ */
+char *
+get_rword(fp)
+       register FILE *fp;
+{
+       static char line[80];
+       register int ch;
+       register char *cp;
+
+       while ((ch = getc(fp)) != EOF)
+               if (ch != ' ' && ch != '\t')
+                       break;
+       if (ch == EOF)
+               return ((char *)EOF);
+       if (ch == '\n')
+               return (NULL);
+       cp = line;
+       *cp++ = ch;
+       while ((ch = getc(fp)) != EOF) {
+           if (isspace(ch) || is_paren(ch))
+                       break;
+               *cp++ = ch;
+       }
+       *cp = 0;
+       if (ch == EOF)
+               return ((char *)EOF);
+       (void) ungetc(ch, fp);
+       return (line);
+}
+/*
+ * get_quoted_word
+ *     like get_word but will accept something in double or single quotes
+ *     (to allow embedded spaces).
+ */
+char *
+get_quoted_word(fp)
+       register FILE *fp;
+{
+       static char line[256];
+       register int ch;
+       register char *cp;
+
+       while ((ch = getc(fp)) != EOF)
+               if (ch != ' ' && ch != '\t')
+                       break;
+       if (ch == EOF)
+               return ((char *)EOF);
+       if (ch == '\n')
+               return (NULL);
+       cp = line;
+       if (ch == '"' || ch == '\'') {
+               register int quote = ch;
+
+               while ((ch = getc(fp)) != EOF) {
+                       if (ch == quote)
+                               break;
+                       if (ch == '\n') {
+                               *cp = 0;
+                               printf("config.old: missing quote reading `%s'\n",
+                                       line);
+                               exit(2);
+                       }
+                       *cp++ = ch;
+               }
+       } else {
+               *cp++ = ch;
+               while ((ch = getc(fp)) != EOF) {
+                       if (isspace(ch))
+                               break;
+                       *cp++ = ch;
+               }
+               if (ch != EOF)
+                       (void) ungetc(ch, fp);
+       }
+       *cp = 0;
+       if (ch == EOF)
+               return ((char *)EOF);
+       return (line);
+}
+
+/*
+ * prepend the path to a filename
+ */
+char *
+path(file)
+       char *file;
+{
+       register char *cp;
+
+#define        CDIR    "../compile/"
+       cp = malloc((unsigned int)(sizeof(CDIR) + strlen(PREFIX) +
+           (file ? strlen(file) : 0) + 2));
+       (void) strcpy(cp, CDIR);
+       (void) strcat(cp, PREFIX);
+       if (file) {
+               (void) strcat(cp, "/");
+               (void) strcat(cp, file);
+       }
+       return (cp);
+}
diff --git a/usr.sbin/config.old/mkglue.c b/usr.sbin/config.old/mkglue.c
new file mode 100644 (file)
index 0000000..874b55e
--- /dev/null
@@ -0,0 +1,408 @@
+/*     $NetBSD: mkglue.c,v 1.10 1995/08/17 17:22:14 thorpej Exp $      */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkglue.c   5.10 (Berkeley) 1/15/91";*/
+static char rcsid[] = "$NetBSD: mkglue.c,v 1.10 1995/08/17 17:22:14 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make the bus adaptor interrupt glue files.
+ */
+#include <stdio.h>
+#include "config.h"
+#include "y.tab.h"
+#include <ctype.h>
+
+/*
+ * Create the UNIBUS interrupt vector glue file.
+ */
+ubglue()
+{
+       register FILE *fp, *gp;
+       register struct device *dp, *mp;
+
+       fp = fopen(path("ubglue.s"), "w");
+       if (fp == 0) {
+               perror(path("ubglue.s"));
+               exit(1);
+       }
+       gp = fopen(path("ubvec.s"), "w");
+       if (gp == 0) {
+               perror(path("ubvec.s"));
+               exit(1);
+       }
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && mp != (struct device *)-1 &&
+                   !eq(mp->d_name, "mba")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               dump_ubavec(fp, id->id,
+                                                   dp->d_unit);
+                                               break;
+                                       }
+                                       if (!strcmp(id->id, id2->id))
+                                               break;
+                               }
+                       }
+               }
+       }
+       dump_std(fp, gp);
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && mp != (struct device *)-1 &&
+                   !eq(mp->d_name, "mba")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               dump_intname(fp, id->id,
+                                                       dp->d_unit);
+                                               break;
+                                       }
+                                       if (!strcmp(id->id, id2->id))
+                                               break;
+                               }
+                       }
+               }
+       }
+       dump_ctrs(fp);
+       (void) fclose(fp);
+       (void) fclose(gp);
+}
+
+static int cntcnt = 0;         /* number of interrupt counters allocated */
+
+/*
+ * Print a UNIBUS interrupt vector.
+ */
+dump_ubavec(fp, vector, number)
+       register FILE *fp;
+       char *vector;
+       int number;
+{
+       char nbuf[80];
+       register char *v = nbuf;
+
+       (void) sprintf(v, "%s%d", vector, number);
+       fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
+           v, v);
+       fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+       if (strncmp(vector, "dzx", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
+       else if (strncmp(vector, "dpx", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
+       else if (strncmp(vector, "dpr", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
+       else {
+               if (strncmp(vector, "uur", 3) == 0) {
+                       fprintf(fp, "#ifdef UUDMA\n");
+                       fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
+                       fprintf(fp, "#endif\n");
+               }
+               fprintf(fp, "\tpushl\t$%d\n", number);
+               fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
+               fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
+       }
+}
+
+/*
+ * Create the VERSAbus interrupt vector glue file.
+ */
+vbglue()
+{
+       register FILE *fp, *gp;
+       register struct device *dp, *mp;
+
+       fp = fopen(path("vbglue.s"), "w");
+       if (fp == 0) {
+               perror(path("vbglue.s"));
+               exit(1);
+       }
+       gp = fopen(path("vbvec.s"), "w");
+       if (gp == 0) {
+               perror(path("vbvec.s"));
+               exit(1);
+       }
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               struct idlst *id, *id2;
+
+               mp = dp->d_conn;
+               if (mp == 0 || mp == (struct device *)-1 ||
+                   eq(mp->d_name, "mba"))
+                       continue;
+               for (id = dp->d_vec; id; id = id->id_next)
+                       for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                               if (id == id2) {
+                                       dump_vbavec(fp, id->id, dp->d_unit);
+                                       break;
+                               }
+                               if (eq(id->id, id2->id))
+                                       break;
+                       }
+       }
+       dump_std(fp, gp);
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && mp != (struct device *)-1 &&
+                   !eq(mp->d_name, "mba")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               dump_intname(fp, id->id,
+                                                       dp->d_unit);
+                                               break;
+                                       }
+                                       if (eq(id->id, id2->id))
+                                               break;
+                               }
+                       }
+               }
+       }
+       dump_ctrs(fp);
+       (void) fclose(fp);
+       (void) fclose(gp);
+}
+
+/*
+ * Print a VERSAbus interrupt vector
+ */
+dump_vbavec(fp, vector, number)
+       register FILE *fp;
+       char *vector;
+       int number;
+{
+       char nbuf[80];
+       register char *v = nbuf;
+
+       (void) sprintf(v, "%s%d", vector, number);
+       fprintf(fp, "SCBVEC(%s):\n", v);
+       fprintf(fp, "\tCHECK_SFE(4)\n");
+       fprintf(fp, "\tSAVE_FPSTAT(4)\n");
+       fprintf(fp, "\tPUSHR\n");
+       fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+       fprintf(fp, "\tpushl\t$%d\n", number);
+       fprintf(fp, "\tcallf\t$8,_%s\n", vector);
+       fprintf(fp, "\tincl\t_cnt+V_INTR\n");
+       fprintf(fp, "\tPOPR\n");
+       fprintf(fp, "\tREST_FPSTAT\n");
+       fprintf(fp, "\trei\n\n");
+}
+
+/*
+ * HP9000/300 interrupts are auto-vectored.
+ * Code is hardwired in locore.s
+ */
+hpglue() {}
+
+/*
+ * so are AMIGA interrupts
+ */
+amigaglue() {}
+
+static char *vaxinames[] = {
+       "clock", "cnr", "cnx", "tur", "tux",
+       "mba0", "mba1", "mba2", "mba3",
+       "uba0", "uba1", "uba2", "uba3"
+};
+static char *tahoeinames[] = {
+       "clock", "cnr", "cnx", "rmtr", "rmtx", "buserr",
+};
+static struct stdintrs {
+       char    **si_names;     /* list of standard interrupt names */
+       int     si_n;           /* number of such names */
+} stdintrs[] = {
+       { vaxinames, sizeof (vaxinames) / sizeof (vaxinames[0]) },
+       { tahoeinames, (sizeof (tahoeinames) / sizeof (tahoeinames[0])) }
+};
+/*
+ * Start the interrupt name table with the names
+ * of the standard vectors not directly associated
+ * with a bus.  Also, dump the defines needed to
+ * reference the associated counters into a separate
+ * file which is prepended to locore.s.
+ */
+dump_std(fp, gp)
+       register FILE *fp, *gp;
+{
+       register struct stdintrs *si = &stdintrs[machine-1];
+       register char **cpp;
+       register int i;
+
+       fprintf(fp, "\n\t.globl\t_intrnames\n");
+       fprintf(fp, "\n\t.globl\t_eintrnames\n");
+       fprintf(fp, "\t.data\n");
+       fprintf(fp, "_intrnames:\n");
+       cpp = si->si_names;
+       for (i = 0; i < si->si_n; i++) {
+               register char *cp, *tp;
+               char buf[80];
+
+               cp = *cpp;
+               if (cp[0] == 'i' && cp[1] == 'n' && cp[2] == 't') {
+                       cp += 3;
+                       if (*cp == 'r')
+                               cp++;
+               }
+               for (tp = buf; *cp; cp++)
+                       if (islower(*cp))
+                               *tp++ = toupper(*cp);
+                       else
+                               *tp++ = *cp;
+               *tp = '\0';
+               fprintf(gp, "#define\tI_%s\t%d\n", buf, i*sizeof (long));
+               fprintf(fp, "\t.asciz\t\"%s\"\n", *cpp);
+               cpp++;
+       }
+}
+
+dump_intname(fp, vector, number)
+       register FILE *fp;
+       char *vector;
+       int number;
+{
+       register char *cp = vector;
+
+       fprintf(fp, "\t.asciz\t\"");
+       /*
+        * Skip any "int" or "intr" in the name.
+        */
+       while (*cp)
+               if (cp[0] == 'i' && cp[1] == 'n' &&  cp[2] == 't') {
+                       cp += 3;
+                       if (*cp == 'r')
+                               cp++;
+               } else {
+                       putc(*cp, fp);
+                       cp++;
+               }
+       fprintf(fp, "%d\"\n", number);
+}
+
+/*
+ * Reserve space for the interrupt counters.
+ */
+dump_ctrs(fp)
+       register FILE *fp;
+{
+       struct stdintrs *si = &stdintrs[machine-1];
+
+       fprintf(fp, "_eintrnames:\n");
+       fprintf(fp, "\n\t.globl\t_intrcnt\n");
+       fprintf(fp, "\n\t.globl\t_eintrcnt\n");
+       fprintf(fp, "\t.align 2\n");
+       fprintf(fp, "_intrcnt:\n");
+       fprintf(fp, "\t.space\t4 * %d\n", si->si_n);
+       fprintf(fp, "_fltintrcnt:\n");
+       fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
+       fprintf(fp, "_eintrcnt:\n\n");
+       fprintf(fp, "\t.text\n");
+}
+
+/*
+ * Create the ISA interrupt vector glue file.
+ */
+i386_vector() {
+       register FILE *fp, *gp;
+       register struct device *dp, *mp;
+       int count;
+
+       fp = fopen(path("vector.h"), "w");
+       if (fp == 0) {
+               perror(path("vector.h"));
+               exit(1);
+       }
+       fprintf(fp, "\
+/*\n\
+ * AT/386\n\
+ * Macros for interrupt vector routines\n\
+ * Generated by config program\n\
+ */\n\
+\n");
+
+       fprintf(fp, "\
+#define BUILD_VECTORS \\\n\
+       BUILD_VECTOR(clk, 0,0,0, _clockmask, _clockintr,1,1,       al);\\\n");
+
+       count=1;
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && /* mp != (struct device *)-1 &&*/
+                   eq(mp->d_name, "isa")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               build_vector(fp, dp, id, count);
+                                               count++;
+                                               if (!strcmp(id->id, id2->id))
+                                                       break;
+                                       }
+                               }
+                       }
+               }
+       }
+       fprintf(fp, "\n\n#define        NR_REAL_INT_HANDLERS    %d\n", count);
+       (void) fclose(fp);
+}
+
+build_vector(fp, dp, id, offset)
+       register FILE *fp;
+       register struct device *dp;
+       struct idlst *id;
+       int offset;
+{
+       fprintf(fp, "\tBUILD_%sVECTOR(%s%d, %d,%d,%d",
+               strcmp(dp->d_name, "sio") == 0 ? "FAST_" : "",
+               dp->d_name, dp->d_unit, dp->d_unit, dp->d_irq, offset);
+       if (eq(dp->d_mask, "null"))
+               fprintf(fp, ", _%s%dmask,", dp->d_name, dp->d_unit);
+       else
+               fprintf(fp, ", _%smask, ", dp->d_mask);
+       fprintf(fp, " _%s,%d,1", id->id, 1 + dp->d_irq / 8);
+       if (dp->d_irq < 8)
+               fprintf(fp, ",       al");
+       else
+               fprintf(fp, "_AND_2, ah");
+       fprintf(fp, ");\\\n");
+}
diff --git a/usr.sbin/config.old/mkheaders.c b/usr.sbin/config.old/mkheaders.c
new file mode 100644 (file)
index 0000000..e3a3db1
--- /dev/null
@@ -0,0 +1,238 @@
+/*     $NetBSD: mkheaders.c,v 1.7 1995/08/17 17:22:15 thorpej Exp $    */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkheaders.c        5.7 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkheaders.c,v 1.7 1995/08/17 17:22:15 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make all the .h files for the optional entries
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "config.h"
+#include "y.tab.h"
+#include "specfile.h"
+
+headers()
+{
+       register struct file_list *fl;
+
+       for (fl = ftab; fl != 0; fl = fl->f_next)
+           if (fl->f_was_driver)
+                   do_identifiers(fl->f_needs);
+           else if (fl->f_needs_count)
+                   do_identifiers(fl->f_countname);
+}
+
+do_identifiers(expr)
+       register struct name_expr *expr;
+{
+
+       if (expr->left)
+               do_identifiers(expr->left);
+       if (expr->type == T_IDENTIFIER)
+               do_count(expr->name, expr->name, 1);
+       if (expr->right)
+               do_identifiers(expr->right);
+}
+
+/*
+ * count all the devices of a certain type and recurse to count
+ * whatever the device is connected to
+ */
+do_count(dev, hname, search)
+       register char *dev, *hname;
+       int search;
+{
+       register struct device *dp, *mp;
+       register int count;
+
+       for (count = 0,dp = dtab; dp != 0; dp = dp->d_next)
+               if (dp->d_unit != -1 && eq(dp->d_name, dev)) {
+                       if (dp->d_type == PSEUDO_DEVICE) {
+                               count =
+                                   dp->d_slave != UNKNOWN ? dp->d_slave : 1;
+                               if (dp->d_flags)
+                                   dev = NULL;
+                               break;
+                       }
+                       count++;
+                       /*
+                        * Allow holes in unit numbering,
+                        * assumption is unit numbering starts
+                        * at zero.
+                        */
+                       if (dp->d_unit + 1 > count)
+                               count = dp->d_unit + 1;
+                       if (search) {
+                               mp = dp->d_conn;
+                               if (mp != 0 && mp != TO_NEXUS &&
+                                   mp->d_conn != 0 && mp->d_conn != TO_NEXUS) {
+                                       do_count(mp->d_name, hname, 0);
+                                       search = 0;
+                               }
+                       }
+               }
+       do_header(dev, hname, count);
+}
+
+do_header(dev, hname, count)
+       char *dev, *hname;
+       int count;
+{
+       char *file, *name, *inw, *toheader(), *tomacro(), *get_rword();
+       struct file_list *fl, *fl_head;
+       FILE *inf, *outf;
+       int inc = 0, oldcount;
+
+       file = toheader(hname);
+       name = tomacro(dev?dev:hname) + (dev == NULL);
+       inf = fopen(file, "r");
+       oldcount = -1;
+       if (inf == 0) {
+               outf = fopen(file, "w");
+               if (outf == 0) {
+                       perror(file);
+                       exit(1);
+               }
+                if (dev || (!dev && count))
+                       fprintf(outf, "#define %s %d\n", name, count);
+               (void) fclose(outf);
+               return;
+       }
+       fl_head = 0;
+       for (;;) {
+               char *cp;
+               if ((inw = get_rword(inf)) == 0 || inw == (char *)EOF)
+                       break;
+               if ((inw = get_rword(inf)) == 0 || inw == (char *)EOF)
+                       break;
+               inw = ns(inw);
+               cp = get_rword(inf);
+               if (cp == 0 || cp == (char *)EOF)
+                       break;
+               inc = atoi(cp);
+               if (eq(inw, name)) {
+                       oldcount = inc;
+                       inc = count;
+               }
+               cp = get_rword(inf);
+               if (cp == (char *)EOF)
+                       break;
+               fl = (struct file_list *) malloc(sizeof *fl);
+               bzero(fl, sizeof(*fl));
+               fl->f_fn = inw;
+               fl->f_type = inc;
+               fl->f_next = fl_head;
+               fl_head = fl;
+       }
+       (void) fclose(inf);
+/*DEBUG  printf("%s: dev=%x, inc=%d, oldcount=%d count=%d\n",
+                file, dev, inc, oldcount, count); */
+       if (!dev && inc == 0 && oldcount == -1 && count == 0)
+               oldcount = 0;
+       else if (!dev && count == 0)
+               oldcount = -1;
+       if (count == oldcount) {
+               for (fl = fl_head; fl;) {
+                       struct file_list *fln = fl->f_next;
+
+                       free((char *)fl);
+                       fl = fln;
+               }
+               return;
+       }
+       if (oldcount == -1) {
+               fl = (struct file_list *) malloc(sizeof *fl);
+               bzero(fl, sizeof(*fl));
+               fl->f_fn = name;
+               fl->f_type = count;
+               fl->f_next = fl_head;
+               fl_head = fl;
+       }
+       outf = fopen(file, "w");
+       if (outf == 0) {
+               perror(file);
+               exit(1);
+       }
+       for (fl = fl_head; fl;) {
+               struct file_list *fln = fl->f_next;
+
+                if (dev || (!dev && count))
+                    fprintf(outf, "#define %s %u\n",
+                            fl->f_fn, count ? fl->f_type : 0);
+               free((char *)fl);
+               fl = fln;
+       }
+       (void) fclose(outf);
+}
+
+/*
+ * convert a dev name to a .h file name
+ */
+char *
+toheader(dev)
+       char *dev;
+{
+       static char hbuf[80];
+
+       (void) strcpy(hbuf, path(dev));
+       (void) strcat(hbuf, ".h");
+       return (hbuf);
+}
+
+/*
+ * convert a dev name to a macro name
+ */
+char *tomacro(dev)
+       register char *dev;
+{
+       static char mbuf[20];
+       register char *cp;
+
+       cp = mbuf;
+       *cp++ = 'N';
+       while (*dev) {
+               if (islower(*dev))
+                   *cp++ = toupper(*dev++);
+               else
+                   *cp++ = *dev++;
+       }
+       *cp++ = 0;
+       return (mbuf);
+}
diff --git a/usr.sbin/config.old/mkioconf.c b/usr.sbin/config.old/mkioconf.c
new file mode 100644 (file)
index 0000000..0d588b8
--- /dev/null
@@ -0,0 +1,1084 @@
+/*     $NetBSD: mkioconf.c,v 1.37 1995/08/17 17:22:17 thorpej Exp $    */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *     must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *     may be used to endorse or promote products derived from this software
+ *     without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkioconf.c 5.18 (Berkeley) 5/10/91";*/
+static char rcsid[] = "$NetBSD: mkioconf.c,v 1.37 1995/08/17 17:22:17 thorpej Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "y.tab.h"
+#include "config.h"
+
+/*
+ * build the ioconf.c file
+ */
+char   *qu();
+char   *intv();
+
+static char *fakepdevs[] = {
+       "ether",                /* XXX */
+       "log",                  /* XXX */
+       NULL,
+};
+
+pseudo_init(fp)
+       FILE *fp;
+{
+       struct device *dp;
+       char **s;
+       int ok, num;
+       
+       fprintf(fp, "\n/* pseudo-devices */\n");
+       for (dp = dtab; dp; dp = dp->d_next) {
+               if (dp->d_type != PSEUDO_DEVICE)
+                       continue;
+               for (ok = 1, s = fakepdevs; *s && ok; s++)
+                       if (strcmp(dp->d_name, *s) == 0)
+                               ok = 0;
+               if (ok == 0)
+                       continue;
+               fprintf(fp, "extern void %sattach __P((int));\n",
+                       dp->d_name);
+       }
+
+       fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n");
+       for (dp = dtab; dp; dp = dp->d_next) {
+               if (dp->d_type != PSEUDO_DEVICE)
+                       continue;
+               for (ok = 1, s = fakepdevs; *s && ok; s++)
+                       if (strcmp(dp->d_name, *s) == 0)
+                               ok = 0;
+               if (ok == 0)
+                       continue;
+               num = dp->d_slave != UNKNOWN ? dp->d_slave : 0;
+               fprintf(fp, "\t{ %sattach, %d },\n",
+                       dp->d_name, num);
+       }
+       fprintf(fp, "\t{ 0, 0 }\n};\n");
+}
+
+#if MACHINE_VAX
+vax_ioconf()
+{
+  register struct device *dp, *mp, *np;
+  register int uba_n, slave;
+  FILE *fp;
+  
+  fp = fopen(path("ioconf.c"), "w");
+  if (fp == 0) {
+    perror(path("ioconf.c"));
+    exit(1);
+  }
+  fprintf(fp, "#include \"vax/include/pte.h\"\n");
+  fprintf(fp, "#include \"sys/param.h\"\n");
+  fprintf(fp, "#include \"sys/device.h\"\n");
+  fprintf(fp, "#include \"sys/buf.h\"\n");
+  fprintf(fp, "#include \"sys/map.h\"\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#include \"vax/mba/mbavar.h\"\n");
+  fprintf(fp, "#include \"vax/uba/ubavar.h\"\n\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#define C (caddr_t)\n\n");
+  /*
+   * First print the mba initialization structures
+   */
+  if (seen_mba) {
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      mp = dp->d_conn;
+      if (mp == 0 || mp == TO_NEXUS ||
+         !eq(mp->d_name, "mba"))
+       continue;
+      fprintf(fp, "extern struct mba_driver %sdriver;\n",
+             dp->d_name);
+    }
+    fprintf(fp, "\nstruct mba_device mbdinit[] = {\n");
+    fprintf(fp, "\t/* Device,  Unit, Mba, Drive, Dk */\n");
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      mp = dp->d_conn;
+      if (dp->d_unit == QUES || mp == 0 ||
+         mp == TO_NEXUS || !eq(mp->d_name, "mba"))
+       continue;
+      if (dp->d_addr) {
+       printf("can't specify csr address on mba for %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_vec != 0) {
+       printf("can't specify vector for %s%d on mba\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_drive == UNKNOWN) {
+       printf("drive not specified for %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_slave != UNKNOWN) {
+       printf("can't specify slave number for %s%d\n", 
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      fprintf(fp, "\t{ &%sdriver, %d,   %s,",
+             dp->d_name, dp->d_unit, qu(mp->d_unit));
+      fprintf(fp, "  %s,  %d },\n",
+             qu(dp->d_drive), dp->d_dk);
+    }
+    fprintf(fp, "\t0\n};\n\n");
+    /*
+     * Print the mbsinit structure
+     * Driver Controller Unit Slave
+     */
+    fprintf(fp, "struct mba_slave mbsinit [] = {\n");
+    fprintf(fp, "\t/* Driver,  Ctlr, Unit, Slave */\n");
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      /*
+       * All slaves are connected to something which
+       * is connected to the massbus.
+       */
+      if ((mp = dp->d_conn) == 0 || mp == TO_NEXUS)
+       continue;
+      np = mp->d_conn;
+      if (np == 0 || np == TO_NEXUS ||
+         !eq(np->d_name, "mba"))
+       continue;
+      fprintf(fp, "\t{ &%sdriver, %s",
+             mp->d_name, qu(mp->d_unit));
+      fprintf(fp, ",  %2d,     %s },\n",
+             dp->d_unit, qu(dp->d_slave));
+    }
+    fprintf(fp, "\t0\n};\n\n");
+  }
+  /*
+   * Now generate interrupt vectors for the unibus
+   */
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    if (dp->d_vec != 0) {
+      struct idlst *ip;
+      mp = dp->d_conn;
+      if (mp == 0 || mp == TO_NEXUS ||
+         (!eq(mp->d_name, "uba") && !eq(mp->d_name, "bi")))
+       continue;
+      fprintf(fp,
+             "extern struct uba_driver %sdriver;\n",
+             dp->d_name);
+      fprintf(fp, "extern ");
+      ip = dp->d_vec;
+      for (;;) {
+       fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
+       ip = ip->id_next;
+       if (ip == 0)
+         break;
+       fprintf(fp, ", ");
+      }
+      fprintf(fp, ";\n");
+      fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
+             dp->d_unit);
+      ip = dp->d_vec;
+      for (;;) {
+       fprintf(fp, "X%s%d", ip->id, dp->d_unit);
+       ip = ip->id_next;
+       if (ip == 0)
+         break;
+       fprintf(fp, ", ");
+      }
+      fprintf(fp, ", 0 } ;\n");
+    }
+  }
+  fprintf(fp, "\nstruct uba_ctlr ubminit[] = {\n");
+  fprintf(fp, "/*\t driver,\tctlr,\tubanum,\talive,\tintr,\taddr */\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
+       !eq(mp->d_name, "uba"))
+      continue;
+    if (dp->d_vec == 0) {
+      printf("must specify vector for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_addr == 0) {
+      printf("must specify csr address for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+      printf("drives need their own entries; dont ");
+      printf("specify drive or slave for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_flags) {
+      printf("controllers (e.g. %s%d) ",
+            dp->d_name, dp->d_unit);
+      printf("don't have flags, only devices do\n");
+      continue;
+    }
+    fprintf(fp,
+           "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0%o },\n",
+           dp->d_name, dp->d_unit, qu(mp->d_unit),
+           dp->d_name, dp->d_unit, dp->d_addr);
+  }
+  fprintf(fp, "\t0\n};\n");
+  /* unibus devices */
+  fprintf(fp, "\nstruct uba_device ubdinit[] = {\n");
+  fprintf(fp,
+         "\t/* driver,  unit, ctlr,  ubanum, slave,    intr,   addr,   dk, flags*/\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
+       mp == TO_NEXUS || mp->d_type == MASTER ||
+       eq(mp->d_name, "mba"))
+      continue;
+    np = mp->d_conn;
+    if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
+      continue;
+    np = 0;
+    if (eq(mp->d_name, "uba")) {
+      if (dp->d_vec == 0) {
+       printf("must specify vector for device %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_addr == 0) {
+       printf("must specify csr for device %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+       printf("drives/slaves can be specified ");
+       printf("only for controllers, ");
+       printf("not for device %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      uba_n = mp->d_unit;
+      slave = QUES;
+    } else {
+      if ((np = mp->d_conn) == 0) {
+       printf("%s%d isn't connected to anything ",
+              mp->d_name, mp->d_unit);
+       printf(", so %s%d is unattached\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      uba_n = np->d_unit;
+      if (dp->d_drive == UNKNOWN) {
+       printf("must specify ``drive number'' ");
+       printf("for %s%d\n", dp->d_name, dp->d_unit);
+       continue;
+      }
+      /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
+      /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
+      if (dp->d_slave != UNKNOWN) {
+       printf("slave numbers should be given only ");
+       printf("for massbus tapes, not for %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_vec != 0) {
+       printf("interrupt vectors should not be ");
+       printf("given for drive %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_addr != 0) {
+       printf("csr addresses should be given only ");
+       printf("on controllers, not on %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      slave = dp->d_drive;
+    }
+    fprintf(fp, "\t{ &%sdriver,  %2d,   %s,",
+           eq(mp->d_name, "uba") ? dp->d_name : mp->d_name, dp->d_unit,
+           eq(mp->d_name, "uba") ? " -1" : qu(mp->d_unit));
+    fprintf(fp, "  %s, %2d,    %s, C 0%-6o,  %d,  0x%x },\n",
+           qu(uba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
+           dp->d_flags);
+  }
+  fprintf(fp, "\t0\n};\n");
+  pseudo_init(fp);
+  (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_TAHOE
+tahoe_ioconf()
+{
+  register struct device *dp, *mp, *np;
+  register int vba_n, slave;
+  FILE *fp;
+  
+  fp = fopen(path("ioconf.c"), "w");
+  if (fp == 0) {
+    perror(path("ioconf.c"));
+    exit(1);
+  }
+  fprintf(fp, "#include \"sys/param.h\"\n");
+  fprintf(fp, "#include \"tahoe/include/pte.h\"\n");
+  fprintf(fp, "#include \"sys/device.h\"\n");
+  fprintf(fp, "#include \"sys/buf.h\"\n");
+  fprintf(fp, "#include \"sys/map.h\"\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#include \"tahoe/vba/vbavar.h\"\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#define C (caddr_t)\n\n");
+  /*
+   * Now generate interrupt vectors for the versabus
+   */
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (mp == 0 || mp == TO_NEXUS || !eq(mp->d_name, "vba"))
+      continue;
+    if (dp->d_vec != 0) {
+      struct idlst *ip;
+      fprintf(fp,
+             "extern struct vba_driver %sdriver;\n",
+             dp->d_name);
+      fprintf(fp, "extern ");
+      ip = dp->d_vec;
+      for (;;) {
+       fprintf(fp, "X%s%d()", ip->id, dp->d_unit);
+       ip = ip->id_next;
+       if (ip == 0)
+         break;
+       fprintf(fp, ", ");
+      }
+      fprintf(fp, ";\n");
+      fprintf(fp, "int\t (*%sint%d[])() = { ", dp->d_name,
+             dp->d_unit);
+      ip = dp->d_vec;
+      for (;;) {
+       fprintf(fp, "X%s%d", ip->id, dp->d_unit);
+       ip = ip->id_next;
+       if (ip == 0)
+         break;
+       fprintf(fp, ", ");
+      }
+      fprintf(fp, ", 0 } ;\n");
+    } else if (dp->d_type == DRIVER)  /* devices w/o interrupts */
+      fprintf(fp,
+             "extern struct vba_driver %sdriver;\n",
+             dp->d_name);
+  }
+  fprintf(fp, "\nstruct vba_ctlr vbminit[] = {\n");
+  fprintf(fp, "/*\t driver,\tctlr,\tvbanum,\talive,\tintr,\taddr */\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 ||
+       !eq(mp->d_name, "vba"))
+      continue;
+    if (dp->d_vec == 0) {
+      printf("must specify vector for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_addr == 0) {
+      printf("must specify csr address for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+      printf("drives need their own entries; dont ");
+      printf("specify drive or slave for %s%d\n",
+            dp->d_name, dp->d_unit);
+      continue;
+    }
+    if (dp->d_flags) {
+      printf("controllers (e.g. %s%d) ",
+            dp->d_name, dp->d_unit);
+      printf("don't have flags, only devices do\n");
+      continue;
+    }
+    fprintf(fp,
+           "\t{ &%sdriver,\t%d,\t%s,\t0,\t%sint%d, C 0x%x },\n",
+           dp->d_name, dp->d_unit, qu(mp->d_unit),
+           dp->d_name, dp->d_unit, dp->d_addr);
+  }
+  fprintf(fp, "\t0\n};\n");
+  /* versabus devices */
+  fprintf(fp, "\nstruct vba_device vbdinit[] = {\n");
+  fprintf(fp,
+         "\t/* driver,  unit, ctlr,  vbanum, slave,    intr,   addr,   dk, flags*/\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_unit == QUES || dp->d_type != DEVICE || mp == 0 ||
+       mp == TO_NEXUS || mp->d_type == MASTER ||
+       eq(mp->d_name, "mba"))
+      continue;
+    np = mp->d_conn;
+    if (np != 0 && np != TO_NEXUS && eq(np->d_name, "mba"))
+      continue;
+    np = 0;
+    if (eq(mp->d_name, "vba")) {
+      if (dp->d_vec == 0)
+       printf(
+              "Warning, no interrupt vector specified for device %s%d\n",
+              dp->d_name, dp->d_unit);
+      if (dp->d_addr == 0) {
+       printf("must specify csr for device %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+       printf("drives/slaves can be specified ");
+       printf("only for controllers, ");
+       printf("not for device %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      vba_n = mp->d_unit;
+      slave = QUES;
+    } else {
+      if ((np = mp->d_conn) == 0) {
+       printf("%s%d isn't connected to anything ",
+              mp->d_name, mp->d_unit);
+       printf(", so %s%d is unattached\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      vba_n = np->d_unit;
+      if (dp->d_drive == UNKNOWN) {
+       printf("must specify ``drive number'' ");
+       printf("for %s%d\n", dp->d_name, dp->d_unit);
+       continue;
+      }
+      /* NOTE THAT ON THE UNIBUS ``drive'' IS STORED IN */
+      /* ``SLAVE'' AND WE DON'T WANT A SLAVE SPECIFIED */
+      if (dp->d_slave != UNKNOWN) {
+       printf("slave numbers should be given only ");
+       printf("for massbus tapes, not for %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_vec != 0) {
+       printf("interrupt vectors should not be ");
+       printf("given for drive %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      if (dp->d_addr != 0) {
+       printf("csr addresses should be given only ");
+       printf("on controllers, not on %s%d\n",
+              dp->d_name, dp->d_unit);
+       continue;
+      }
+      slave = dp->d_drive;
+    }
+    fprintf(fp, "\t{ &%sdriver,  %2d,   %s,",
+           eq(mp->d_name, "vba") ? dp->d_name : mp->d_name, dp->d_unit,
+           eq(mp->d_name, "vba") ? " -1" : qu(mp->d_unit));
+    fprintf(fp, "  %s, %2d,    %s, C 0x%-6x,  %d,  0x%x },\n",
+           qu(vba_n), slave, intv(dp), dp->d_addr, dp->d_dk,
+           dp->d_flags);
+  }
+  fprintf(fp, "\t0\n};\n");
+  pseudo_init(fp);
+  (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_HP300
+hp300_ioconf()
+{
+  register struct device *dp, *mp, *np;
+  register int hpib, slave;
+  FILE *fp;
+  extern char *wnum();
+  
+  fp = fopen(path("ioconf.c"), "w");
+  if (fp == 0) {
+    perror(path("ioconf.c"));
+    exit(1);
+  }
+  fprintf(fp, "#include \"sys/param.h\"\n");
+  fprintf(fp, "#include \"sys/device.h\"\n");
+  fprintf(fp, "#include \"sys/buf.h\"\n");
+  fprintf(fp, "#include \"sys/map.h\"\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#include \"hp300/dev/device.h\"\n\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#define C (caddr_t)\n");
+  fprintf(fp, "#define D (struct driver *)\n\n");
+  /*
+   * First print the hpib controller initialization structures
+   */
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_unit == QUES || mp == 0)
+      continue;
+    fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+  }
+  fprintf(fp, "\nstruct hp_ctlr hp_cinit[] = {\n");
+  fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (dp->d_unit == QUES ||
+       dp->d_type != MASTER && dp->d_type != CONTROLLER)
+      continue;
+    if (mp != TO_NEXUS) {
+      printf("%s%s must be attached to an sc (nexus)\n",
+            dp->d_name, wnum(dp->d_unit));
+      continue;
+    }
+    if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+      printf("can't specify drive/slave for %s%s\n",
+            dp->d_name, wnum(dp->d_unit));
+      continue;
+    }
+    fprintf(fp,
+           "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n",
+           dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+  }
+  fprintf(fp, "\t0\n};\n");
+  /* devices */
+  fprintf(fp, "\nstruct hp_device hp_dinit[] = {\n");
+  fprintf(fp,
+         "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n");
+  for (dp = dtab; dp != 0; dp = dp->d_next) {
+    mp = dp->d_conn;
+    if (mp == 0 || dp->d_type != DEVICE || hpbadslave(mp, dp))
+      continue;
+    if (mp == TO_NEXUS) {
+      if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+       printf("can't specify drive/slave for %s%s\n",
+              dp->d_name, wnum(dp->d_unit));
+       continue;
+      }
+      slave = QUES;
+      hpib = QUES;
+    } else {
+      if (dp->d_addr != 0) {
+       printf("can't specify sc for device %s%s\n",
+              dp->d_name, wnum(dp->d_unit));
+       continue;
+      }
+      if (mp->d_type == CONTROLLER) {
+       if (dp->d_drive == UNKNOWN) {
+         printf("must specify drive for %s%s\n",
+                dp->d_name, wnum(dp->d_unit));
+         continue;
+       }
+       slave = dp->d_drive;
+      } else {
+       if (dp->d_slave == UNKNOWN) {
+         printf("must specify slave for %s%s\n",
+                dp->d_name, wnum(dp->d_unit));
+         continue;
+       }
+       slave = dp->d_slave;
+      }
+      hpib = mp->d_unit;
+    }
+    fprintf(fp, "{ &%sdriver,\t", dp->d_name);
+    if (mp == TO_NEXUS)
+      fprintf(fp, "D 0x0,\t");
+    else
+      fprintf(fp, "&%sdriver,", mp->d_name);
+    fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
+           dp->d_unit, hpib, slave,
+           dp->d_addr, dp->d_dk, dp->d_flags);
+  }
+  fprintf(fp, "0\n};\n");
+  pseudo_init(fp);
+  (void) fclose(fp);
+}
+
+#define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi"))
+#define isscsidev(n) (eq(n,"sd") || eq(n,"st"))
+
+hpbadslave(mp, dp)
+     register struct device *dp, *mp;
+{
+  extern char *wnum();
+  
+  if (mp == TO_NEXUS && ishpibdev(dp->d_name) ||
+      mp != TO_NEXUS && eq(mp->d_name, "hpib") &&
+      !ishpibdev(dp->d_name)) {
+    printf("%s%s must be attached to an hpib\n",
+          dp->d_name, wnum(dp->d_unit));
+    return (1);
+  }
+  if (mp == TO_NEXUS && isscsidev(dp->d_name) ||
+      mp != TO_NEXUS && eq(mp->d_name, "scsi") &&
+      !isscsidev(dp->d_name)) {
+    printf("%s%s must be attached to a scsi\n",
+          dp->d_name, wnum(dp->d_unit));
+    return (1);
+  }
+  return (0);
+}
+
+char *
+  wnum(num)
+{
+  
+  if (num == QUES || num == UNKNOWN)
+    return ("?");
+  (void) sprintf(errbuf, "%d", num);
+  return (errbuf);
+}
+#endif
+
+#if MACHINE_I386
+char *shandler();
+char *sirq();
+
+i386_ioconf()
+{
+  register struct device *dp, *mp, *np;
+  register int seq = 0;
+  FILE *fp;
+  
+  fp = fopen(path("ioconf.c"), "w");
+  if (fp == 0) {
+    perror(path("ioconf.c"));
+    exit(1);
+  }
+  fprintf(fp, "/*\n");
+  fprintf(fp, " * ioconf.c \n");
+  fprintf(fp, " * Generated by config.old program\n");
+  fprintf(fp, " */\n\n");
+  fprintf(fp, "#include <sys/param.h>\n");
+  fprintf(fp, "#include <sys/device.h>\n");
+  fprintf(fp, "#include <sys/buf.h>\n");
+  fprintf(fp, "#include <machine/pte.h>\n");
+  fprintf(fp, "\n");
+  fprintf(fp, "#define C (caddr_t)\n");
+  fprintf(fp, "#define D &isa_devtab\n");
+  fprintf(fp, "\n");
+  /*
+   * First print the isa initialization structures
+   */
+  if (seen_isa) {
+    
+    fprintf(fp, "/*\n");
+    fprintf(fp, " * ISA devices\n");
+    fprintf(fp, " */\n\n");
+    fprintf(fp, "#include <i386/isa/isa_device.h>\n");
+    fprintf(fp, "#include <i386/isa/isa.h>\n");
+    fprintf(fp, "#include <i386/isa/icu.h>\n\n");
+    
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      mp = dp->d_conn;
+      if (mp == 0 || mp == TO_NEXUS)
+       continue;
+      fprintf(fp, "extern struct cfdriver %7scd;\n",
+             dp->d_name);
+      if (dp->d_irq == 2) {
+       fprintf(stderr, "remapped irq 2 to irq 9, please update your config file\n");
+       dp->d_irq = 9;
+      }
+    }
+
+    fprintf(fp, "\nstruct isa_device isa_devtab[] = {\n");
+    fprintf(fp, "\
+/*    driver    iobase    irq drq      maddr   msiz unit   flags phys parent */\n");
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      mp = dp->d_conn;
+      if (mp == 0 || mp == TO_NEXUS)
+       continue;
+      dp->d_seq = seq++;
+    }
+    for (dp = dtab; dp != 0; dp = dp->d_next) {
+      mp = dp->d_conn;
+      if (mp == 0 || mp == TO_NEXUS)
+       continue;
+      fprintf(fp, "{ &%7scd,", dp->d_name);
+      if (dp->d_port)
+        fprintf(fp, " %8s,", dp->d_port);
+      else
+        fprintf(fp, "   0x%04x,", dp->d_portn);
+      fprintf(fp, " %5s, %2d, C 0x%05x, %5d,  %2d, 0x%04x, %3d",
+             sirq(dp->d_irq), dp->d_drq, dp->d_maddr, dp->d_msize,
+             dp->d_unit, dp->d_flags,
+             eq(mp->d_name, "isa") ? 0 :
+             dp->d_drive == UNKNOWN ? dp->d_slave : dp->d_drive);
+      if (eq(mp->d_name, "isa"))
+        fprintf(fp, ",  NULL");
+      else
+        fprintf(fp, ", D[%2d]", mp->d_seq);
+      fprintf(fp, " },\n");
+    }
+    fprintf(fp, "0\n};\n");
+  }
+  pseudo_init(fp);
+  (void) fclose(fp);
+}
+
+/*
+ * XXX - there should be a general function to print devtabs instead of these
+ * little pieces of it.
+ */
+
+char *
+  sirq(int i)
+{
+  static char buf[20];
+  
+#if 0
+  sprintf(buf, "%d", i);
+  return buf;
+#else
+  switch(i) {
+  case -2:
+    return "0";
+  case -1:
+    return "-1";
+  default:
+    sprintf(buf, "IRQ%d", i);
+    return buf;
+  }
+#endif
+}
+
+char *
+  shandler(dp)
+struct device *dp;
+{
+  static char buf[32+20];
+  
+  if(dp->d_irq==-2)
+    return ("NULL");
+  sprintf(buf, "X%.32s%d", dp->d_name, dp->d_unit);
+  return buf;
+}
+#endif
+
+#if MACHINE_PC532
+pc532_ioconf()
+{
+       struct device *dp, *mp, *np;
+       int uba_n, slave;
+       FILE *fp;
+
+       fp = fopen(path("ioconf.c"), "w");
+       if (fp == 0) {
+               perror(path("ioconf.c"));
+               exit(1);
+       }
+       fprintf(fp, "/*\n");
+       fprintf(fp, " * ioconf.c \n");
+       fprintf(fp, " * Generated by config.old program\n");
+       fprintf(fp, " */\n\n");
+       fprintf(fp, "#include \"../../dev/device.h\"\n");
+       fprintf(fp, "#include <types.h>\n");
+       fprintf(fp, "#include <cdefs.h>\n");
+       fprintf(fp, "#include <device.h>\n");
+       fprintf(fp, "\n");
+
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+          mp = dp->d_conn;
+          if (dp->d_unit == QUES || mp == 0)
+               continue;
+          fprintf(fp, "extern struct pc532_driver %sdriver;\n", mp->d_name);
+       }
+
+       fprintf(fp, "\nstruct pc532_device pc532_devtab_bio[] = {\n");
+       fprintf(fp, "/* driver  name    unit    drive   flags alive */\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+           mp = dp->d_conn;
+           if (mp == 0 || !eq(dp->d_mask, "bio"))
+               continue;
+           fprintf (fp, "{&%sdriver,\t\"%s\",\t%d,\t%d,\t%d,\t0},\n",
+               mp->d_name, dp->d_name, dp->d_unit, dp->d_drive, dp->d_flags);
+       }
+       fprintf(fp, "0\n};\n");
+
+       fprintf(fp, "\nstruct pc532_device pc532_devtab_tty[] = {\n");
+       fprintf(fp, "/* driver  name    unit    scsiid  flags alive */\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+           mp = dp->d_conn;
+           if (mp == 0 || !eq(dp->d_mask, "tty"))
+               continue;
+           fprintf (fp, "{&%sdriver,\t\"%s\",\t%d,\t0,\t0,\t0},\n",
+                mp->d_name, dp->d_name, dp->d_unit);
+       }
+       fprintf(fp, "0\n};\n");
+
+       fprintf(fp, "\nstruct pc532_device pc532_devtab_net[] = {\n");
+       fprintf(fp, "/* driver  unit    scsiid  alive */\n");
+       fprintf(fp, "0\n};\n");
+
+       pseudo_init(fp);
+       (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_PMAX
+pmax_ioconf()
+{
+       register struct device *dp, *mp;
+       FILE *fp;
+
+       fp = fopen(path("ioconf.c"), "w");
+       if (fp == 0) {
+               perror(path("ioconf.c"));
+               exit(1);
+       }
+       fprintf(fp, "/*\n");
+       fprintf(fp, " * ioconf.c \n");
+       fprintf(fp, " * Generated by config.old program\n");
+       fprintf(fp, " */\n\n");
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/types.h\"\n");
+       fprintf(fp, "#include \"sys/device.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#include \"pmax/dev/device.h\"\n\n");
+       fprintf(fp, "#define C (char *)\n\n");
+
+       /* print controller initialization structures */
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               if (dp->d_type == PSEUDO_DEVICE)
+                       continue;
+               fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+       }
+       fprintf(fp, "\nstruct pmax_ctlr pmax_cinit[] = {\n");
+       fprintf(fp, "/*\tdriver,\t\tunit,\taddr,\t\tflags */\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               if (dp->d_type != CONTROLLER && dp->d_type != MASTER)
+                       continue;
+               if (dp->d_conn != TO_NEXUS) {
+                       printf("%s%s must be attached to a nexus (internal bus)\n",
+                               dp->d_name, wnum(dp->d_unit));
+                       continue;
+               }
+               if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+                       printf("can't specify drive/slave for %s%s\n",
+                               dp->d_name, wnum(dp->d_unit));
+                       continue;
+               }
+               if (dp->d_unit == UNKNOWN || dp->d_unit == QUES)
+                       dp->d_unit = 0;
+               fprintf(fp,
+                       "\t{ &%sdriver,\t%d,\tC 0x%x,\t0x%x },\n",
+                       dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+       }
+       fprintf(fp, "\t0\n};\n");
+
+       /* print devices connected to other controllers */
+       fprintf(fp, "\nstruct scsi_device scsi_dinit[] = {\n");
+       fprintf(fp,
+          "/*driver,\tcdriver,\tunit,\tctlr,\tdrive,\tslave,\tdk,\tflags*/\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               if (dp->d_type == CONTROLLER || dp->d_type == MASTER ||
+                   dp->d_type == PSEUDO_DEVICE)
+                       continue;
+               mp = dp->d_conn;
+               if (mp == 0 || 
+                       (!eq(mp->d_name, "asc") && !eq(mp->d_name, "sii"))) {
+                       printf("%s%s: devices must be attached to a SCSI controller\n",
+                               dp->d_name, wnum(dp->d_unit));
+                       continue;
+               }
+               if ((unsigned)dp->d_drive > 6) {
+                       printf("%s%s: SCSI drive must be in the range 0..6\n",
+                               dp->d_name, wnum(dp->d_unit));
+                       continue;
+               }
+               /* may want to allow QUES later */
+               if ((unsigned)dp->d_slave > 7) {
+                       printf("%s%s: SCSI slave (LUN) must be in the range 0..7\n",
+                               dp->d_name, wnum(dp->d_unit));
+                       continue;
+               }
+               fprintf(fp, "{ &%sdriver,\t&%sdriver,", dp->d_name, mp->d_name);
+               fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t%d,\t0x%x },\n",
+                       dp->d_unit, mp->d_unit, dp->d_drive, dp->d_slave,
+                       dp->d_dk, dp->d_flags);
+       }
+       fprintf(fp, "0\n};\n");
+       pseudo_init(fp);
+       (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_AMIGA
+amiga_ioconf()
+{
+       register struct device *dp, *mp, *np;
+       register int controller, slave;
+       FILE *fp;
+       extern char *awnum();
+
+       fp = fopen(path("ioconf.c"), "w");
+       if (fp == 0) {
+               perror(path("ioconf.c"));
+               exit(1);
+       }
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#include \"arch/amiga/dev/device.h\"\n\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#define C (caddr_t)\n");
+       fprintf(fp, "#define D (struct driver *)\n\n");
+       /*
+        * First print the controller initialization structures
+        */
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (dp->d_unit == QUES || mp == 0)
+                       continue;
+               fprintf(fp, "extern struct driver %sdriver;\n", dp->d_name);
+       }
+       fprintf(fp, "\nstruct amiga_ctlr amiga_cinit[] = {\n");
+       fprintf(fp, "/*\tdriver,\t\tunit,\talive,\taddr,\tflags */\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (dp->d_unit == QUES ||
+                       dp->d_type != MASTER && dp->d_type != CONTROLLER)
+                       continue;
+               if (mp != TO_NEXUS) {
+                       printf("%s%s must be attached to an controller\n",
+                               dp->d_name, awnum(dp->d_unit));
+                       continue;
+               }
+               if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+                       printf("can't specify drive/slave for %s%s\n",
+                               dp->d_name, awnum(dp->d_unit));
+                       continue;
+               }
+               fprintf(fp,
+                       "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t0x%x },\n",
+                       dp->d_name, dp->d_unit, dp->d_addr, dp->d_flags);
+       }
+       fprintf(fp, "\t0\n};\n");
+/* devices */
+       fprintf(fp, "\nstruct amiga_device amiga_dinit[] = {\n");
+       fprintf(fp,
+          "/*driver,\tcdriver,\tunit,\tctlr,\tslave,\taddr,\tdk,\tflags*/\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp == 0 || dp->d_type != DEVICE || amigabadslave(mp, dp))
+                       continue;
+               if (mp == TO_NEXUS) {
+                       if (dp->d_drive != UNKNOWN || dp->d_slave != UNKNOWN) {
+                               printf("can't specify drive/slave for %s%s\n",
+                                       dp->d_name, awnum(dp->d_unit));
+                               continue;
+                       }
+                       slave = QUES;
+                       controller = QUES;
+               } else {
+                       if (dp->d_addr != 0) {
+                               printf("can't specify manufacturer/product for device %s%s\n",
+                                       dp->d_name, awnum(dp->d_unit));
+                               continue;
+                       }
+                       if (mp->d_type == CONTROLLER) {
+                               if (dp->d_drive == UNKNOWN) {
+                                       printf("must specify drive for %s%s\n",
+                                               dp->d_name, awnum(dp->d_unit));
+                                       continue;
+                               }
+                               slave = dp->d_drive;
+                       } else {
+                               if (dp->d_slave == UNKNOWN) {
+                                       printf("must specify slave for %s%s\n",
+                                               dp->d_name, awnum(dp->d_unit));
+                                       continue;
+                               }
+                               slave = dp->d_slave;
+                       }
+                       controller = mp->d_unit;
+               }
+               fprintf(fp, "{ &%sdriver,\t", dp->d_name);
+               if (mp == TO_NEXUS)
+                       fprintf(fp, "D 0x0,\t");
+               else
+                       fprintf(fp, "&%sdriver,", mp->d_name);
+               fprintf(fp, "\t%d,\t%d,\t%d,\tC 0x%x,\t%d,\t0x%x },\n",
+                       dp->d_unit, controller, slave,
+                       dp->d_addr, dp->d_dk, dp->d_flags);
+       }
+       fprintf(fp, "0\n};\n");
+       pseudo_init(fp);
+       (void) fclose(fp);
+}
+
+#define isscsidev(n) (eq(n,"sd") || eq(n,"st"))
+
+amigabadslave(mp, dp)
+       register struct device *dp, *mp;
+{
+       extern char *awnum();
+
+       if (mp == TO_NEXUS && isscsidev(dp->d_name) ||
+           mp != TO_NEXUS && eq(mp->d_name, "scsi") &&
+           !isscsidev(dp->d_name)) {
+               printf("%s%s must be attached to a scsi\n",
+                      dp->d_name, awnum(dp->d_unit));
+               return (1);
+       }
+       return (0);
+}
+
+char *
+awnum(num)
+{
+
+       if (num == QUES || num == UNKNOWN)
+               return ("?");
+       (void) sprintf(errbuf, "%d", num);
+       return (errbuf);
+}
+#endif
+
+
+char *
+intv(dev)
+register struct device *dev;
+{
+       static char buf[20];
+  
+       if (dev->d_vec == 0)
+               return ("       0");
+       (void) sprintf(buf, "%sint%d", dev->d_name, dev->d_unit);
+       return (buf);
+}
+
+char *
+qu(num)
+{
+       if (num == QUES)
+               return ("'?'");
+       if (num == UNKNOWN)
+               return (" -1");
+       (void) sprintf(errbuf, "%3d", num);
+       return (errbuf);
+}
diff --git a/usr.sbin/config.old/mkmakefile.c b/usr.sbin/config.old/mkmakefile.c
new file mode 100644 (file)
index 0000000..69b1a1c
--- /dev/null
@@ -0,0 +1,496 @@
+/*     $NetBSD: mkmakefile.c,v 1.28 1995/08/17 17:22:18 thorpej Exp $  */
+
+/*
+ * Copyright (c) 1980,1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkmakefile.c       5.33 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkmakefile.c,v 1.28 1995/08/17 17:22:18 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Build the makefile for the system, from
+ * the information in the files files and the
+ * additional files for the machine being compiled to.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <machine/param.h>
+#include "y.tab.h"
+#include "config.h"
+
+#define next_word(fp, wd) \
+       { register char *word = get_word(fp); \
+         if (word == (char *)EOF) \
+               return; \
+         else \
+               wd = word; \
+       }
+#define next_quoted_word(fp, wd) \
+       { register char *word = get_quoted_word(fp); \
+         if (word == (char *)EOF) \
+               return; \
+         else \
+               wd = word; \
+       }
+
+static struct file_list *fcur;
+char *tail();
+
+/*
+ * Lookup a file, by name.
+ */
+struct file_list *
+fl_lookup(file)
+       register char *file;
+{
+       register struct file_list *fp;
+
+       for (fp = ftab ; fp != 0; fp = fp->f_next) {
+               if (eq(fp->f_fn, file))
+                       return (fp);
+       }
+       return (0);
+}
+
+/*
+ * Lookup a file, by final component name.
+ */
+struct file_list *
+fltail_lookup(file)
+       register char *file;
+{
+       register struct file_list *fp;
+
+       for (fp = ftab ; fp != 0; fp = fp->f_next) {
+               if (eq(tail(fp->f_fn), tail(file)))
+                       return (fp);
+       }
+       return (0);
+}
+
+/*
+ * Make a new file list entry
+ */
+struct file_list *
+new_fent()
+{
+       register struct file_list *fp;
+
+       fp = (struct file_list *) malloc(sizeof *fp);
+       bzero(fp, sizeof *fp);
+       if (fcur == 0)
+               fcur = ftab = fp;
+       else
+               fcur->f_next = fp;
+       fcur = fp;
+       return (fp);
+}
+
+static struct users {
+       int     u_default;
+       int     u_min;
+       int     u_max;
+} users[] = {
+       { 24, 8, 1024 },                /* MACHINE_VAX */
+       { 4, 2, 128 },                  /* MACHINE_TAHOE */
+       { 8, 2, 64 },                   /* MACHINE_HP300 */
+       { 8, 2, 64 },                   /* MACHINE_I386 */
+       { 8, 2, 64 },                   /* MACHINE_PC532 */
+       { 8, 2, 64 },                   /* MACHINE_PMAX */
+       { 8, 2, 64 },                   /* MACHINE_AMIGA */
+};
+#define        NUSERS  (sizeof (users) / sizeof (users[0]))
+
+/*
+ * Build the makefile from the skeleton
+ */
+makefile()
+{
+       FILE *ifp, *ofp;
+       char line[BUFSIZ];
+       struct opt *op;
+       struct users *up;
+
+       read_files();
+       strcpy(line, "Makefile.");
+       (void) strcat(line, machinename);
+       ifp = fopen(line, "r");
+       if (ifp == 0) {
+               perror(line);
+               exit(1);
+       }
+       ofp = fopen(path("Makefile"), "w");
+       if (ofp == 0) {
+               perror(path("Makefile"));
+               exit(1);
+       }
+       fprintf(ofp, "KERN_IDENT=%s\n", raisestr(ident));               /* 29 Jun 92*/
+       fprintf(ofp, "IDENT=-D%s", raisestr(ident));
+       if (profiling)
+               fprintf(ofp, " -DGPROF");
+       if (cputype == 0) {
+               printf("cpu type must be specified\n");
+               exit(1);
+       }
+       { struct cputype *cp;
+         for (cp = cputype; cp; cp = cp->cpu_next)
+               fprintf(ofp, " -D%s", cp->cpu_name);
+       }
+       for (op = opt; op; op = op->op_next)
+               if (op->op_value)
+                       fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
+               else
+                       fprintf(ofp, " -D%s", op->op_name);
+       fprintf(ofp, "\n");
+       if (hadtz == 0)
+               printf("timezone not specified; gmt assumed\n");
+       if ((unsigned)machine > NUSERS) {
+               printf("maxusers config info isn't present, using vax\n");
+               up = &users[MACHINE_VAX-1];
+       } else
+               up = &users[machine-1];
+       if (maxusers == 0) {
+               printf("maxusers not specified; %d assumed\n", up->u_default);
+               maxusers = up->u_default;
+       } else if (maxusers < up->u_min) {
+               printf("minimum of %d maxusers assumed\n", up->u_min);
+               maxusers = up->u_min;
+       } else if (maxusers > up->u_max)
+               printf("warning: maxusers > %d (%d)\n", up->u_max, maxusers);
+        fprintf(ofp, "PARAM=-DTIMEZONE=%d -DDST=%d -DMAXUSERS=%d\n",
+                zone, dst, maxusers);
+       if (loadaddress != -1) {
+                fprintf(ofp, "LOAD_ADDRESS=%X\n", loadaddress);
+        }
+       for (op = mkopt; op; op = op->op_next)
+               fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
+       if (debugging)
+               fprintf(ofp, "DEBUG=-g\n");
+       if (profiling)
+               fprintf(ofp, "PROF=-pg\n");
+       while (fgets(line, BUFSIZ, ifp) != 0) {
+               if (*line != '%') {
+                       fprintf(ofp, "%s", line);
+                       continue;
+               }
+               if (eq(line, "%OBJS\n"))
+                       do_objs(ofp);
+               else if (eq(line, "%CFILES\n"))
+                       do_cfiles(ofp);
+               else if (eq(line, "%RULES\n"))
+                       do_rules(ofp);
+               else if (eq(line, "%LOAD\n"))
+                       do_load(ofp);
+               else
+                       fprintf(stderr,
+                           "Unknown %% construct in generic makefile: %s",
+                           line);
+       }
+       (void) fclose(ifp);
+       (void) fclose(ofp);
+}
+
+/*
+ * Read in the information about files used in making the system.
+ * Store it in the ftab linked list.
+ */
+read_files()
+{
+       register struct file_list *fl;
+       char fname[48];
+
+       ftab = 0;
+       (void) strcpy(fname, "../../../conf/files.oldconf");
+       read_file(fname,1,0);
+       (void) sprintf(fname, "files.%s.oldconf", machinename);
+       read_file(fname,1,0);
+       if (strcmp(machinearch, machinename)) {
+               (void) sprintf(fname, "../../%s/conf/files.%s.oldconf",
+                   machinearch, machinearch);
+               read_file(fname,1,0);
+       }
+       (void) sprintf(fname, "files.%s.oldconf", raisestr(ident));
+       read_file(fname,0,1);
+       (void) strcpy(fname, "../../../conf/options.oldconf");
+       read_file(fname,0,0);
+       (void) sprintf(fname, "options.%s.oldconf", machinename);
+       read_file(fname,0,0);
+       if (strcmp(machinearch, machinename)) {
+               (void) sprintf(fname, "../../%s/conf/options.%s.oldconf",
+                   machinearch, machinearch);
+               read_file(fname,0,0);
+       }
+       (void) sprintf(fname, "options.%s.oldconf", raisestr(ident));
+       read_file(fname,0,1);
+}
+
+opteq(cp, dp)
+       char *cp, *dp;
+{
+       char c, d;
+
+       for (; ; cp++, dp++) {
+               if (*cp != *dp) {
+                       c = isupper(*cp) ? tolower(*cp) : *cp;
+                       d = isupper(*dp) ? tolower(*dp) : *dp;
+                       if (c != d)
+                               return (0);
+               }
+               if (*cp == 0)
+                       return (1);
+       }
+}
+
+do_objs(fp)
+       FILE *fp;
+{
+       register struct file_list *tp, *fl;
+       register int lpos, len;
+       register char *cp, och, *sp;
+       char swapname[32];
+
+       fprintf(fp, "OBJS=");
+       lpos = 6;
+       for (tp = ftab; tp != 0; tp = tp->f_next) {
+               if (tp->f_type == INVISIBLE)
+                       continue;
+               if (tp->f_type == PROFILING && !profiling)
+                       continue;
+               sp = tail(tp->f_fn);
+               for (fl = conf_list; fl; fl = fl->f_next) {
+                       if (fl->f_type != SWAPSPEC)
+                               continue;
+                       (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+                       if (eq(sp, swapname))
+                               goto cont;
+               }
+               cp = sp + (len = strlen(sp)) - 1;
+               och = *cp;
+               *cp = 'o';
+               if (len + lpos > 72) {
+                       lpos = 8;
+                       fprintf(fp, "\\\n\t");
+               }
+               fprintf(fp, "%s ", sp);
+               lpos += len + 1;
+               *cp = och;
+cont:
+               ;
+       }
+       if (lpos != 8)
+               putc('\n', fp);
+}
+
+do_cfiles(fp)
+       FILE *fp;
+{
+       register struct file_list *tp, *fl;
+       register int lpos, len;
+       char swapname[32];
+
+       fputs("CFILES=", fp);
+       lpos = 8;
+       for (tp = ftab; tp; tp = tp->f_next) {
+               if (tp->f_type == INVISIBLE)
+                       continue;
+               if (tp->f_type == PROFILING && !profiling)
+                       continue;
+               len = strlen(tp->f_fn);
+               if (tp->f_fn[len - 1] != 'c')
+                       continue;
+               if ((len = 3 + len) + lpos > 72) {
+                       lpos = 8;
+                       fputs("\\\n\t", fp);
+               }
+               fprintf(fp, "$S/%s ", tp->f_fn);
+               lpos += len + 1;
+       }
+       for (fl = conf_list; fl; fl = fl->f_next)
+               if (fl->f_type == SYSTEMSPEC) {
+                       (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+                       if ((len = 3 + strlen(swapname)) + lpos > 72) {
+                               lpos = 8;
+                               fputs("\\\n\t", fp);
+                       }
+                       if (eq(fl->f_fn, "generic"))
+                               fprintf(fp, "$S/arch/%s/%s/%s ",
+                                   machinename, machinename, swapname);
+                       else if (eq(fl->f_fn, "nfs"))
+                               fprintf(fp, "$S/nfs/%s ", swapname);
+                       else
+                               fprintf(fp, "%s ", swapname);
+                       lpos += len + 1;
+               }
+       if (lpos != 8)
+               putc('\n', fp);
+}
+
+char *
+tail(fn)
+       char *fn;
+{
+       register char *cp;
+
+       cp = rindex(fn, '/');
+       if (cp == 0)
+               return (fn);
+       return (cp+1);
+}
+
+/*
+ * Create the makerules for each file
+ * which is part of the system.
+ * Devices are processed with the special c2 option -i
+ * which avoids any problem areas with i/o addressing
+ * (e.g. for the VAX); assembler files are processed by as.
+ */
+do_rules(f)
+       FILE *f;
+{
+       register char *cp, *np, och, *tp;
+       register struct file_list *ftp;
+       char *special;
+
+       for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
+               if (ftp->f_type == INVISIBLE)
+                       continue;
+               if (ftp->f_type == PROFILING && !profiling)
+                       continue;
+               cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
+               och = *cp;
+               *cp = '\0';
+               if (och == 'o') {
+                       fprintf(f, "%so:\n\t-cp $S/%so .\n\n", tail(np), np);
+                       continue;
+               }
+               fprintf(f, "%so: $S/%s%c\n", tail(np), np, och);
+               tp = tail(np);
+               special = ftp->f_special;
+               if (special == 0) {
+                       char *ftype;
+                       static char cmd[128];
+
+                       switch (ftp->f_type) {
+
+                       case NORMAL:
+                               ftype = "NORMAL";
+                               break;
+
+                       case DRIVER:
+                               ftype = "DRIVER";
+                               break;
+
+                       case PROFILING:
+                               ftype = "PROFILE";
+                               break;
+
+                       default:
+                               printf("config.old: don't know rules for %s\n", np);
+                               break;
+                       }
+                       (void)sprintf(cmd, "${%s_%c%s}", ftype, toupper(och),
+                                     ftp->f_flags & CONFIGDEP? "_C" : "");
+                       special = cmd;
+               }
+               *cp = och;
+               fprintf(f, "\t%s\n\n", special);
+       }
+}
+
+/*
+ * Create the load strings
+ */
+do_load(f)
+       register FILE *f;
+{
+       register struct file_list *fl;
+       register int first;
+       struct file_list *do_systemspec();
+
+       for (first = 1, fl = conf_list; fl; first = 0)
+               fl = fl->f_type == SYSTEMSPEC ?
+                       do_systemspec(f, fl, first) : fl->f_next;
+       fputs("all:", f);
+       for (fl = conf_list; fl; fl = fl->f_next)
+               if (fl->f_type == SYSTEMSPEC)
+                       fprintf(f, " %s", fl->f_needs->name);
+       putc('\n', f);
+}
+
+struct file_list *
+do_systemspec(f, fl, first)
+       FILE *f;
+       register struct file_list *fl;
+       int first;
+{
+       fprintf(f, "SYSTEM_SWAP_DEP+= swap%s.o\n", fl->f_fn);
+       fprintf(f, "%s: ${SYSTEM_DEP} swap%s.o vers.o", fl->f_needs->name, fl->f_fn);
+       fprintf(f, "\n\t${SYSTEM_LD_HEAD}\n");
+       fprintf(f, "\t${SYSTEM_LD} swap%s.o\n", fl->f_fn);
+       fprintf(f, "\t${SYSTEM_LD_TAIL}\n\n");
+       do_swapspec(f, fl->f_fn);
+       for (fl = fl->f_next; fl && fl->f_type == SWAPSPEC; fl = fl->f_next)
+               ;
+       return (fl);
+}
+
+do_swapspec(f, name)
+       FILE *f;
+       register char *name;
+{
+
+       if (eq(name, "generic"))
+               fprintf(f, "swapgeneric.o: ../../%s/swapgeneric.c\n",
+                       machinename);
+       else if (eq(name, "nfs"))
+               fprintf(f, "swapnfs.o: ../../../../nfs/swapnfs.c\n");
+       else
+               fprintf(f, "swap%s.o: swap%s.c\n", name, name);
+       fprintf(f, "\t${NORMAL_C}\n\n");
+}
+
+char *
+raisestr(str)
+       register char *str;
+{
+       register char *cp = str;
+
+       while (*str) {
+               if (islower(*str))
+                       *str = toupper(*str);
+               str++;
+       }
+       return (cp);
+}
diff --git a/usr.sbin/config.old/mkswapconf.c b/usr.sbin/config.old/mkswapconf.c
new file mode 100644 (file)
index 0000000..9e52ff2
--- /dev/null
@@ -0,0 +1,240 @@
+/*     $NetBSD: mkswapconf.c,v 1.11 1995/08/17 17:22:20 thorpej Exp $  */
+
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkswapconf.c       5.10 (Berkeley) 7/1/91";*/
+static char rcsid[] = "$NetBSD: mkswapconf.c,v 1.11 1995/08/17 17:22:20 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Build a swap configuration file.
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+swapconf()
+{
+       register struct file_list *fl;
+       struct file_list *do_swap();
+
+       fl = conf_list;
+       while (fl) {
+               if (fl->f_type != SYSTEMSPEC) {
+                       fl = fl->f_next;
+                       continue;
+               }
+               fl = do_swap(fl);
+       }
+}
+
+struct file_list *
+do_swap(fl)
+       register struct file_list *fl;
+{
+       FILE *fp;
+       char  swapname[80];
+       register struct file_list *swap;
+       dev_t dev;
+
+       if (eq(fl->f_fn, "generic") || eq(fl->f_fn, "nfs")) {
+               fl = fl->f_next;
+               return (fl->f_next);
+       }
+       (void) sprintf(swapname, "swap%s.c", fl->f_fn);
+       fp = fopen(path(swapname), "w");
+       if (fp == 0) {
+               perror(path(swapname));
+               exit(1);
+       }
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/conf.h\"\n");
+       fprintf(fp, "\n");
+       /*
+        * If there aren't any swap devices
+        * specified, just return, the error
+        * has already been noted.
+        */
+       swap = fl->f_next;
+       if (swap == 0 || swap->f_type != SWAPSPEC) {
+               (void) unlink(path(swapname));
+               fclose(fp);
+               return (swap);
+       }
+       fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\n",
+               major(fl->f_rootdev), minor(fl->f_rootdev));
+       fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\n",
+               major(fl->f_dumpdev), minor(fl->f_dumpdev));
+       fprintf(fp, "\n");
+       fprintf(fp, "struct\tswdevt swdevt[] = {\n");
+       do {
+               dev = swap->f_swapdev;
+               fprintf(fp, "\t{ makedev(%d, %d),\t0,\t%d },\t/* %s */\n",
+                   major(dev), minor(dev), swap->f_swapsize, swap->f_fn);
+               swap = swap->f_next;
+       } while (swap && swap->f_type == SWAPSPEC);
+       fprintf(fp, "\t{ NODEV, 0, 0 }\n");
+       fprintf(fp, "};\n\n");
+       fprintf(fp, "extern int ffs_mountroot();\n");
+       fprintf(fp, "int (*mountroot)() = ffs_mountroot;\n");
+       fclose(fp);
+       return (swap);
+}
+
+static int devtablenotread = 1;
+static struct devdescription {
+       char    *dev_name;
+       int     dev_major;
+       struct  devdescription *dev_next;
+} *devtable;
+
+/*
+ * Given a device name specification figure out:
+ *     major device number
+ *     partition
+ *     device name
+ *     unit number
+ * This is a hack, but the system still thinks in
+ * terms of major/minor instead of string names.
+ */
+dev_t
+nametodev(name, defunit, defpartition)
+       char *name;
+       int defunit;
+       char defpartition;
+{
+       char *cp, partition;
+       int unit;
+       register struct devdescription *dp;
+
+       cp = name;
+       if (cp == 0) {
+               fprintf(stderr, "config.old: internal error, nametodev\n");
+               exit(1);
+       }
+       while (*cp && !isdigit(*cp))
+               cp++;
+       unit = *cp ? atoi(cp) : defunit;
+       if (unit < 0 || unit > 31) {
+               fprintf(stderr,
+"config.old: %s: invalid device specification, unit out of range\n", name);
+               unit = defunit;                 /* carry on more checking */
+       }
+       if (*cp) {
+               *cp++ = '\0';
+               while (*cp && isdigit(*cp))
+                       cp++;
+       }
+       partition = *cp ? *cp : defpartition;
+       if (partition < 'a' || partition > 'h') {
+               fprintf(stderr,
+"config.old: %c: invalid device specification, bad partition\n", *cp);
+               partition = defpartition;       /* carry on */
+       }
+       if (devtablenotread)
+               initdevtable();
+       for (dp = devtable; dp; dp = dp->dev_next)
+               if (eq(name, dp->dev_name))
+                       break;
+       if (dp == 0) {
+               fprintf(stderr, "config.old: %s: unknown device\n", name);
+               return (NODEV);
+       }
+       return (makedev(dp->dev_major, (unit << 3) + (partition - 'a')));
+}
+
+char *
+devtoname(dev)
+       dev_t dev;
+{
+       char buf[80]; 
+       register struct devdescription *dp;
+
+       if (devtablenotread)
+               initdevtable();
+       for (dp = devtable; dp; dp = dp->dev_next)
+               if (major(dev) == dp->dev_major)
+                       break;
+       if (dp == 0)
+               dp = devtable;
+       (void) sprintf(buf, "%s%d%c", dp->dev_name,
+               minor(dev) >> 3, (minor(dev) & 07) + 'a');
+       return (ns(buf));
+}
+
+initdevtable()
+{
+       char linebuf[256];
+       char buf[BUFSIZ];
+       int maj;
+       register struct devdescription **dp = &devtable;
+       FILE *fp;
+
+       if (machinename==NULL) {
+               fprintf(stderr, "config.old: machine not specified\n");
+               exit(1);
+       }
+       (void) sprintf(buf, "../conf/devices.%s.oldconf", machinename);
+       fp = fopen(buf, "r");
+       if (fp == NULL) {
+               fprintf(stderr, "config.old: ");
+               perror(buf);
+               exit(1);
+       }
+       while(fgets(linebuf,256,fp))
+       {
+               /*******************************\
+               * Allow a comment               *
+               \*******************************/
+               if(linebuf[0] == '#') continue;
+       
+               if (sscanf(linebuf, "%s\t%d\n", buf, &maj) == 2)
+               {
+                       *dp = (struct devdescription *)malloc(sizeof (**dp));
+                       (*dp)->dev_name = ns(buf);
+                       (*dp)->dev_major = maj;
+                       dp = &(*dp)->dev_next;
+               }
+               else
+               {
+                       fprintf(stderr,"illegal line in devices file\n");
+                       break;
+               }
+       }
+       *dp = 0;
+       fclose(fp);
+       devtablenotread = 0;
+}
diff --git a/usr.sbin/config.old/mkubglue.c b/usr.sbin/config.old/mkubglue.c
new file mode 100644 (file)
index 0000000..472ff68
--- /dev/null
@@ -0,0 +1,199 @@
+/*     $NetBSD: mkubglue.c,v 1.3 1995/08/17 17:22:21 thorpej Exp $     */
+
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)mkubglue.c 5.3 (Berkeley) 4/19/91";*/
+static char rcsid[] = "$NetBSD: mkubglue.c,v 1.3 1995/08/17 17:22:21 thorpej Exp $";
+#endif /* not lint */
+
+/*
+ * Make the uba interrupt file ubglue.s
+ */
+#include <stdio.h>
+#include "config.h"
+#include "y.tab.h"
+
+ubglue()
+{
+       register FILE *fp;
+       register struct device *dp, *mp;
+
+       fp = fopen(path("ubglue.s"), "w");
+       if (fp == 0) {
+               perror(path("ubglue.s"));
+               exit(1);
+       }
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && mp != (struct device *)-1 &&
+                   !eq(mp->d_name, "mba")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               dump_vec(fp, id->id, dp->d_unit);
+                                               break;
+                                       }
+                                       if (!strcmp(id->id, id2->id))
+                                               break;
+                               }
+                       }
+               }
+       }
+       dump_std(fp);
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if (mp != 0 && mp != (struct device *)-1 &&
+                   !eq(mp->d_name, "mba")) {
+                       struct idlst *id, *id2;
+
+                       for (id = dp->d_vec; id; id = id->id_next) {
+                               for (id2 = dp->d_vec; id2; id2 = id2->id_next) {
+                                       if (id2 == id) {
+                                               dump_intname(fp, id->id,
+                                                       dp->d_unit);
+                                               break;
+                                       }
+                                       if (!strcmp(id->id, id2->id))
+                                               break;
+                               }
+                       }
+               }
+       }
+       dump_ctrs(fp);
+       (void) fclose(fp);
+}
+
+static int cntcnt = 0;         /* number of interrupt counters allocated */
+
+/*
+ * print an interrupt vector
+ */
+dump_vec(fp, vector, number)
+       register FILE *fp;
+       char *vector;
+       int number;
+{
+       char nbuf[80];
+       register char *v = nbuf;
+
+       (void) sprintf(v, "%s%d", vector, number);
+       fprintf(fp, "\t.globl\t_X%s\n\t.align\t2\n_X%s:\n\tpushr\t$0x3f\n",
+           v, v);
+       fprintf(fp, "\tincl\t_fltintrcnt+(4*%d)\n", cntcnt++);
+       if (strncmp(vector, "dzx", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdzdma\n\n", number);
+       else if (strncmp(vector, "dpx", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdpxdma\n\n", number);
+       else if (strncmp(vector, "dpr", 3) == 0)
+               fprintf(fp, "\tmovl\t$%d,r0\n\tjmp\tdprdma\n\n", number);
+       else {
+               if (strncmp(vector, "uur", 3) == 0) {
+                       fprintf(fp, "#ifdef UUDMA\n");
+                       fprintf(fp, "\tmovl\t$%d,r0\n\tjsb\tuudma\n", number);
+                       fprintf(fp, "#endif\n");
+               }
+               fprintf(fp, "\tpushl\t$%d\n", number);
+               fprintf(fp, "\tcalls\t$1,_%s\n\tpopr\t$0x3f\n", vector);
+               fprintf(fp, "\tincl\t_cnt+V_INTR\n\trei\n\n");
+       }
+}
+
+/*
+ * Start the interrupt name table with the names
+ * of the standard vectors not on the unibus.
+ * The number and order of these names should correspond
+ * with the definitions in scb.s.
+ */
+dump_std(fp)
+       register FILE *fp;
+{
+       fprintf(fp, "\n\t.globl\t_intrnames\n");
+       fprintf(fp, "\n\t.globl\t_eintrnames\n");
+       fprintf(fp, "\t.data\n");
+       fprintf(fp, "_intrnames:\n");
+       fprintf(fp, "\t.asciz\t\"clock\"\n");
+       fprintf(fp, "\t.asciz\t\"cnr\"\n");
+       fprintf(fp, "\t.asciz\t\"cnx\"\n");
+       fprintf(fp, "\t.asciz\t\"tur\"\n");
+       fprintf(fp, "\t.asciz\t\"tux\"\n");
+       fprintf(fp, "\t.asciz\t\"mba0\"\n");
+       fprintf(fp, "\t.asciz\t\"mba1\"\n");
+       fprintf(fp, "\t.asciz\t\"mba2\"\n");
+       fprintf(fp, "\t.asciz\t\"mba3\"\n");
+       fprintf(fp, "\t.asciz\t\"uba0\"\n");
+       fprintf(fp, "\t.asciz\t\"uba1\"\n");
+       fprintf(fp, "\t.asciz\t\"uba2\"\n");
+       fprintf(fp, "\t.asciz\t\"uba3\"\n");
+#define        I_FIXED         13                      /* number of names above */
+}
+
+dump_intname(fp, vector, number)
+       register FILE *fp;
+       char *vector;
+       int number;
+{
+       register char *cp = vector;
+
+       fprintf(fp, "\t.asciz\t\"");
+       /*
+        * Skip any "int" or "intr" in the name.
+        */
+       while (*cp)
+               if (cp[0] == 'i' && cp[1] == 'n' &&  cp[2] == 't') {
+                       cp += 3;
+                       if (*cp == 'r')
+                               cp++;
+               } else {
+                       putc(*cp, fp);
+                       cp++;
+               }
+       fprintf(fp, "%d\"\n", number);
+}
+
+dump_ctrs(fp)
+       register FILE *fp;
+{
+       fprintf(fp, "_eintrnames:\n");
+       fprintf(fp, "\n\t.globl\t_intrcnt\n");
+       fprintf(fp, "\n\t.globl\t_eintrcnt\n");
+       fprintf(fp, "_intrcnt:\n", I_FIXED);
+       fprintf(fp, "\t.space\t4 * %d\n", I_FIXED);
+       fprintf(fp, "_fltintrcnt:\n", cntcnt);
+       fprintf(fp, "\t.space\t4 * %d\n", cntcnt);
+       fprintf(fp, "_eintrcnt:\n\n");
+       fprintf(fp, "\t.text\n");
+}
diff --git a/usr.sbin/config.old/specfile.c b/usr.sbin/config.old/specfile.c
new file mode 100644 (file)
index 0000000..54375fc
--- /dev/null
@@ -0,0 +1,601 @@
+/*     $NetBSD: specfile.c,v 1.10 1995/08/17 17:22:22 thorpej Exp $    */
+
+#ifndef lint
+static char rcsid[] = "$NetBSD: specfile.c,v 1.10 1995/08/17 17:22:22 thorpej Exp $";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include "y.tab.h"
+#include "config.h"
+#include "specfile.h"
+
+#define is_paren(x) ((x == '(') || (x == ')'))
+struct file_keyword {
+    char *key;
+    int token;
+} file_kw_table[] = {
+    "compile-with",            T_COMPILE_WITH,
+    "config-dependent",        T_CONFIG_DEPENDENT,
+    "device-driver",           T_DEVICE_DRIVER,
+    "optional",                T_OPTIONAL,
+    "or",                      T_OR,
+    "not",                     T_NOT,
+    "requires",                T_REQUIRES,
+    "standard",                T_STANDARD,
+    "needs-count",            T_NEEDS_COUNT,
+    };
+
+extern struct file_list *fltail_lookup(),*new_fent(),*fl_lookup();
+static char *current_file;
+static int current_line;
+static jmp_buf parse_problem;
+
+int file_tok(token)
+     char *token;
+{
+    int i, length;
+
+    if (is_paren(*token))
+       return (*token == '(' ?  T_LEFTPAREN : T_RIGHTPAREN);
+    for (i =0; i <(sizeof(file_kw_table)/sizeof(file_kw_table[0])); i++) {
+       if (!strcmp(file_kw_table[i].key, token))
+           return file_kw_table[i].token;
+    }
+    length = strlen(token);
+    for (i = 0; i < length; i++) {
+       if (!isalnum(token[i]) && (token[i] != '_') &&
+           (token[i] != '-')) return -1;
+    }
+    return T_IDENTIFIER;
+}
+
+struct name_expr *
+alloc_name_expr(name)
+     char *name;
+{
+    struct name_expr *new;
+    int token,type;
+
+    type = 0;
+    token = file_tok(name);
+    switch (token) {
+    case T_OR: 
+    case T_NOT: 
+    case T_IDENTIFIER: 
+    case T_LEFTPAREN:
+    case T_RIGHTPAREN:
+       type = token;
+       break;
+    default: return NULL;
+    }
+    new = malloc(sizeof(struct name_expr));
+    new->type = type;
+    if (type == T_IDENTIFIER) new->name = ns(name);
+    else new->name = NULL;
+    new->left = new->right = new->next = NULL;
+    return new;
+}
+
+void parse_err(char *emessage)
+{
+    fprintf(stderr, "%s:%d: %s\n", current_file, current_line, emessage);
+    if (!fatal_errors) longjmp(parse_problem,1);
+    exit(1);
+}
+
+delete_expr(expr)
+     struct name_expr *expr;
+{
+    if (expr->type == T_IDENTIFIER)
+       free(expr->name);
+    free(expr);
+}
+struct name_expr *yank_node(expr)
+     struct name_expr **expr;
+{
+    struct name_expr *node;
+
+    if (*expr == NULL) return NULL;
+    node = *expr;
+    *expr = (*expr)->next;
+    return node;
+}
+struct name_expr *yank_expr(expr)
+     struct name_expr **expr;
+{
+    struct name_expr *node,*tail, *subexpr,*next;
+
+    node = yank_node(expr);
+    if (node == NULL) return NULL;
+    if (node->type == T_LEFTPAREN) 
+       for (tail = subexpr = NULL;;) {
+           next = yank_expr(expr);
+           if (!next) parse_err("missing ')'");
+           if (next->type == T_RIGHTPAREN) {
+               if (subexpr == NULL)
+                   parse_err("empty inner expression i.e '()' ");
+               node->left = subexpr;
+               node->type = EXPR_GROUP;
+               break;
+           } else {
+               if (subexpr == NULL)
+                   tail = subexpr = next;
+               else {
+                   tail->next = next;
+                   tail = next;
+               }
+               tail->next = NULL;
+           }
+       }
+    return(node);
+}
+
+struct name_expr *
+paren_squish(tree)
+     struct name_expr *tree;
+{
+    struct name_expr *result,*expr,*tail;
+    
+    result = tail = NULL;
+
+    while ((expr = yank_expr(&tree)) != NULL) {
+       if (expr->type == T_RIGHTPAREN)
+           parse_err("unexpected ')'");
+       if (result == NULL) {
+           tail = result = expr;
+       }
+       else {
+           tail->next = expr;
+           tail = expr;
+       }
+       tail->next = NULL;
+    }
+    return(result);
+}
+
+struct name_expr *
+not_squish(tree)
+     struct name_expr *tree;
+{
+    struct name_expr *result,*next,*tail,*node;
+
+    tail = result = next = NULL;
+    
+    while ((next = yank_node(&tree)) != NULL) {
+       if (next->type == EXPR_GROUP)
+           next->left = not_squish(next->left);
+       if (next->type == T_NOT) {
+           int notlevel = 1;
+           
+           node = yank_node(&tree);
+           while (node->type == T_NOT) {
+               ++notlevel;
+               node = yank_node(&tree);
+           }
+           if (node == NULL)
+               parse_err("no expression following 'not'");
+           if (node->type == T_OR)
+               parse_err("nothing between 'not' and 'or'");
+           if (notlevel % 2 != 1)
+               next = node;
+           else
+               next->left = node;
+       }
+       
+       /* add the node to our result plan */
+       if (result == NULL)
+           tail = result = next;
+       else {
+           tail->next = next;
+           tail = next;
+       }
+       tail->next = NULL;
+    }
+    return(result);
+}
+struct name_expr *
+or_squish(tree)
+     struct name_expr *tree;
+{
+    struct name_expr *next, *tail,*result;
+    
+    tail = result = next = NULL;
+    
+    while ((next = yank_node(&tree)) != NULL) {
+       
+       if (next->type == EXPR_GROUP)
+           next->left = or_squish(next->left);
+       
+       if (next->type == T_NOT)
+           next->left = or_squish(next->left);
+       
+       if (next->type == T_OR) {
+           if (result == NULL)
+               parse_err("no expression before 'or'");
+           next->left = result;
+           next->right = or_squish(tree);
+           if (next->right == NULL)
+               parse_err("no expression after 'or'");
+           next->next = NULL;
+           return(next);
+       }
+       
+       /* add the node to our result plan */
+       if (result == NULL)
+           tail = result = next;
+       else {
+           tail->next = next;
+           tail = next;
+       }
+       tail->next = NULL;
+    }
+    return(result);
+}
+
+struct name_expr *
+parse_name_expr(fp,seed, read_ahead)
+     FILE *fp;
+     char *seed, **read_ahead;
+{
+    struct name_expr *list, *tail,*new,*current;
+    char *str;
+
+
+    list = NULL;
+    *read_ahead = NULL;
+    if (seed) {
+       list = alloc_name_expr(seed);
+       if (list == NULL) {
+           *read_ahead = seed;
+           return NULL;
+       }
+    }
+    tail = list;
+    for (;;) {
+       str = get_word(fp);
+       if ((str == (char *)EOF) || str == NULL) {
+           *read_ahead = str;
+           break;
+       }
+       new = alloc_name_expr(str);
+       if (!new) {
+           *read_ahead = str;
+           break;
+       }
+       if (tail) tail->next = new;
+       else {
+           list = new;
+       }
+       tail = new;
+    }
+    list = paren_squish(list);
+    list = not_squish(list);
+    list = or_squish(list);
+    return list;
+}
+int is_simple(expr)
+     struct name_expr *expr;
+{
+    return expr && expr->type == T_IDENTIFIER;
+}
+
+int f_not(expr,explain)
+     struct name_expr *expr;
+     int explain;
+{
+    int result;
+
+    result = !depend_check(expr->left,explain);
+    return result;
+}
+int f_or(expr,explain)
+     struct name_expr *expr;
+     int explain;
+{
+    int result;
+
+    if (depend_check(expr->left,explain))
+       return 1;
+    if (depend_check(expr->right,explain))
+       return 1;
+    return 0;
+}
+int f_identifier(expr,explain)
+     struct name_expr *expr;
+     int explain;
+{
+    struct opt *op;
+    struct device *dp;
+    struct cputype *cp;
+
+    for (op = opt; op != 0; op = op->op_next)
+       if (opteq(op->op_name, expr->name)) return 1;
+    for (cp = cputype; cp != 0; cp = cp->cpu_next)
+       if (opteq(cp->cpu_name, expr->name)) return 1;
+    for (dp = dtab; dp != 0; dp = dp->d_next)
+       if (eq(dp->d_name, expr->name) &&
+           !(dp->d_type == PSEUDO_DEVICE && dp->d_flags && dp->d_slave == 0)) return 1;
+    return 0;
+}
+print_expr(expr)
+     struct name_expr *expr;
+{
+    struct name_expr *current;
+    for (current = expr; current != NULL; current= current->next) {
+       switch (current->type) {
+       case T_NOT:
+           fprintf (stderr, "not ");
+           print_expr(current->left);
+           break;
+       case T_OR:
+           print_expr(current->left);
+           fprintf (stderr, "or ");
+           print_expr(current->right);
+           break;
+       case EXPR_GROUP:
+           fprintf (stderr, "(");
+           print_expr(current->left);
+           fprintf (stderr, ")");
+           break;
+       case T_IDENTIFIER:
+           fprintf(stderr,"%s ", current->name);
+           break;
+       default:
+           parse_err("unknown expression type");
+       }
+    }
+}
+int depend_check(expr, explain)
+     struct name_expr *expr;
+     int explain;
+{
+    struct name_expr *current;
+    int result;
+
+    for (current= expr; current; current= current->next) {
+       switch(current->type) {
+       case T_NOT:
+           result = f_not(current,0);
+           break;
+       case T_OR:
+           result = f_or(current,0);
+           break;
+       case EXPR_GROUP:
+           result = depend_check(current->left, 0);
+           break;
+       case T_IDENTIFIER:
+           result = f_identifier(current,0);
+           break;
+       }
+       if (result) continue;
+       return 0;
+    }
+    return 1;
+}
+
+
+
+read_file(filename, fatal_on_open, override)
+     char *filename;
+     int fatal_on_open, override;
+{
+    FILE *fp;
+    size_t length;
+    char ebuf[1024];
+    
+    fp = fopen(filename, "r");
+    if (!fp)
+       if (fatal_on_open) {
+           perror(filename);
+           exit(1);
+       }
+       else return;
+    current_line = 0;
+    current_file = filename;
+    for (;;) {
+       char *str, *kf_name, *read_ahead,*compile_with;
+       extern char *get_word(),*get_quoted_word();
+       int token,optional,driver,needs_count,config_depend,
+            is_dup,filetype,is_option;
+       struct name_expr *depends_on,*requires;
+       struct file_list *tp,*tmp, *fl,*pf;     
+       enum {BEFORE_FILENAME,BEFORE_SPEC,BEFORE_DEPENDS,PAST_DEPENDS,
+                 SPECIALS} parse_state;
+
+
+       if (setjmp(parse_problem)) {
+           while (1) {
+               str = get_word(fp);
+               if (!str || (str == (char *) EOF)) break;
+           }
+           if (!str) current_line++;
+           continue;
+       }
+       str = get_word(fp);
+       current_line++;
+       if (str == NULL) continue;
+       if (str == (char *) EOF) break;
+       if (*str == '#') {
+           fprintf(stderr, "shouldn't get here");
+           exit(1);
+       }
+       parse_state = BEFORE_FILENAME;
+       kf_name = read_ahead = compile_with = NULL;
+       optional= driver = config_depend = filetype = needs_count = 0;
+       depends_on = requires = NULL;
+       is_dup = 0;
+       is_option = 0;
+       while ((str != NULL) && (str != (char *)EOF)) {
+           switch (parse_state) {
+           case BEFORE_FILENAME: {
+               kf_name = ns(str);
+                if (strncmp(kf_name, "OPTIONS/", 8) == 0) {
+                    kf_name = ns(index(kf_name, '/') + 1);
+                    is_option++;
+                }
+               parse_state = BEFORE_SPEC;
+               break;
+           }
+           case BEFORE_SPEC: {
+               token = file_tok(str);
+               if ((token != T_OPTIONAL) && (token != T_STANDARD))
+                   parse_err("unexpected token starts inclusion specification");
+               optional = (token == T_OPTIONAL);
+               parse_state = BEFORE_DEPENDS;
+               break;
+           }
+           case BEFORE_DEPENDS: {
+               depends_on = parse_name_expr(fp,str, &read_ahead);
+               str = read_ahead;
+               parse_state = PAST_DEPENDS;
+               continue;
+               break;
+           }
+           case PAST_DEPENDS:
+           case SPECIALS: 
+               token = file_tok(str);
+               switch (token) {
+               case T_COMPILE_WITH:  {
+                   str = get_quoted_word(fp);
+                   if ((str == 0) || (str == (char *) EOF))
+                       parse_err("missing compile command string");
+                   compile_with = ns(str);
+               }
+               case T_CONFIG_DEPENDENT: {
+                   config_depend = 1;
+                   break;
+               }
+               case T_DEVICE_DRIVER: {
+                   driver = 1;
+                   needs_count = 0;
+                   break;
+               }
+               case T_REQUIRES: {
+                   requires = parse_name_expr(fp,NULL, &read_ahead);
+                   if (!requires) 
+                       parse_err("'requires' but no expression");
+                   str = read_ahead;                   
+                   continue;
+                   break;
+               }
+               case T_NEEDS_COUNT: {
+                   if (!driver) needs_count = 1;
+                   break;
+               }
+               default:
+                   parse_err("unexpected token");
+               }
+               break;
+           default:
+               parse_err("unknown state");
+           }
+           str = get_word(fp);
+       }
+       if (parse_state == BEFORE_SPEC)
+           parse_err("filename, but no specification");
+       if (is_option) {
+            struct device dev;
+            register struct opt *op;
+            struct opt *lop = 0;
+            /*
+             *  Allocate a pseudo-device entry which we will insert into
+             *  the device list below.  The flags field is set non-zero to
+             *  indicate an internal entry rather than one generated from
+             *  the configuration file.  The slave field is set to define
+             *  the corresponding symbol as 0 should we fail to find the
+             *  option in the option list.
+             */
+            init_dev(&dev);
+            dev.d_type = PSEUDO_DEVICE;
+            dev.d_name = ns(kf_name);
+            dev.d_slave = 0;
+            dev.d_flags++;
+            for (op=opt; op; lop=op, op=op->op_next) {
+                char *od = raisestr(ns(kf_name));
+                /*
+                 *  Found an option which matches the current device
+                 *  dependency identifier.  Set the slave field to
+                 *  define the option in the header file.
+                 */
+                if (strcmp(op->op_name, od) == 0) {
+                    dev.d_slave = 1;
+                    if (lop == 0)
+                        opt = op->op_next;
+                    else
+                        lop->op_next = op->op_next;
+                    free(op);
+                    op = 0;
+                }
+                free(od);
+                if (op == 0)
+                        break;
+            }
+            newdev(&dev);
+            needs_count = 0;
+           driver = 1;
+            filetype = INVISIBLE;
+       }
+       else {
+            if (!kf_name)
+                parse_err("no filename specified");
+            fl = fl_lookup(kf_name);
+            if (fl && !override) {
+                (void) sprintf(ebuf, "duplicate file name '%s'", kf_name);
+                parse_err(ebuf);
+            }
+            if ((pf = fl_lookup(kf_name)) &&
+                (pf->f_type != INVISIBLE || (pf->f_flags | DUPLICATE)))
+                is_dup = 1;
+            else
+                is_dup = 0;
+            if (override && ((tmp = fltail_lookup(kf_name)) != 0)) {
+                    fprintf(stderr, "%s:%d: Local file %s overrides %s.\n",
+                            current_file, current_line, kf_name, tmp->f_fn);
+                   tmp->f_type = INVISIBLE;
+           }
+            if (!optional) {
+                if (driver)
+                    parse_err("'standard' incompatible with 'device-driver'");
+                if (depends_on && !needs_count)
+                    parse_err("'standard' can't have dependencies");
+           }
+            else if (!depends_on) 
+                parse_err("'optional' requires dependency specification");
+            if (is_simple(depends_on) &&
+                eq("profiling-routine", depends_on->name)) filetype = PROFILING;
+            else if (!optional || depend_check(depends_on,0)) filetype = NORMAL;
+            else filetype = INVISIBLE;
+
+            if (filetype == NORMAL && requires && !depend_check(requires,0)) {
+                fprintf(stderr, "%s:%d: requirement expression failed: ",
+                        current_file, current_line);
+                print_expr(requires);
+                fprintf(stderr, "\n");
+                parse_err("requirements not met");
+           }
+       }
+       tp = new_fent();
+       tp->f_fn = kf_name;
+       tp->f_type = filetype;
+       if (driver)
+           tp->f_needs = depends_on;
+       else
+           tp->f_needs = NULL;
+       if (needs_count)
+           tp->f_countname = depends_on;
+       else
+           tp->f_countname = NULL;
+       tp->f_was_driver = driver;
+       tp->f_needs_count = needs_count;
+       tp->f_special = compile_with;
+       tp->f_flags = 0;
+       tp->f_flags |= (config_depend ? CONFIGDEP : 0);
+       tp->f_flags |= (is_dup ? DUPLICATE : 0);
+    }
+    return;
+
+}
diff --git a/usr.sbin/config.old/specfile.h b/usr.sbin/config.old/specfile.h
new file mode 100644 (file)
index 0000000..873b892
--- /dev/null
@@ -0,0 +1,16 @@
+/*     $NetBSD: specfile.h,v 1.2 1995/08/17 17:22:23 thorpej Exp $     */
+
+#define T_OPTIONAL            1
+#define T_STANDARD            2
+#define T_COMPILE_WITH        3
+#define T_CONFIG_DEPENDENT    4
+#define T_DEVICE_DRIVER       5
+#define T_PROFILING_ROUTINE   6
+#define T_IDENTIFIER          7
+#define T_OR                  8
+#define T_REQUIRES            9
+#define T_NOT                10
+#define EXPR_GROUP           11
+#define T_LEFTPAREN          12
+#define T_RIGHTPAREN         13
+#define T_NEEDS_COUNT       14