BSD 4_4 release
[unix-history] / usr / src / usr.sbin / config / mkioconf.c
index c36253b..e3622cb 100644 (file)
@@ -1,24 +1,38 @@
 /*
 /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)mkioconf.c 5.14 (Berkeley) 6/1/90";
+static char sccsid[] = "@(#)mkioconf.c 8.1 (Berkeley) 6/6/93";
 #endif /* not lint */
 
 #include <stdio.h>
 #endif /* not lint */
 
 #include <stdio.h>
@@ -30,6 +44,8 @@ static char sccsid[] = "@(#)mkioconf.c        5.14 (Berkeley) 6/1/90";
  */
 char   *qu();
 char   *intv();
  */
 char   *qu();
 char   *intv();
+char   *wnum();
+void   pseudo_ioconf();
 
 #if MACHINE_VAX
 vax_ioconf()
 
 #if MACHINE_VAX
 vax_ioconf()
@@ -43,14 +59,13 @@ vax_ioconf()
                perror(path("ioconf.c"));
                exit(1);
        }
                perror(path("ioconf.c"));
                exit(1);
        }
-       fprintf(fp, "#include \"machine/pte.h\"\n");
-       fprintf(fp, "#include \"../sys/param.h\"\n");
-       fprintf(fp, "#include \"../sys/buf.h\"\n");
-       fprintf(fp, "#include \"../sys/map.h\"\n");
-       fprintf(fp, "#include \"../sys/vm.h\"\n");
+       fprintf(fp, "#include \"vax/include/pte.h\"\n");
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "#include \"sys/map.h\"\n");
        fprintf(fp, "\n");
        fprintf(fp, "\n");
-       fprintf(fp, "#include \"../vaxmba/mbavar.h\"\n");
-       fprintf(fp, "#include \"../vaxuba/ubavar.h\"\n\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");
        /*
        fprintf(fp, "\n");
        fprintf(fp, "#define C (caddr_t)\n\n");
        /*
@@ -271,6 +286,7 @@ vax_ioconf()
                    dp->d_flags);
        }
        fprintf(fp, "\t0\n};\n");
                    dp->d_flags);
        }
        fprintf(fp, "\t0\n};\n");
+       pseudo_ioconf(fp);
        (void) fclose(fp);
 }
 #endif
        (void) fclose(fp);
 }
 #endif
@@ -287,12 +303,12 @@ tahoe_ioconf()
                perror(path("ioconf.c"));
                exit(1);
        }
                perror(path("ioconf.c"));
                exit(1);
        }
-       fprintf(fp, "#include \"../sys/param.h\"\n");
-       fprintf(fp, "#include \"machine/pte.h\"\n");
-       fprintf(fp, "#include \"../sys/buf.h\"\n");
-       fprintf(fp, "#include \"../sys/map.h\"\n");
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"tahoe/include/pte.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "#include \"sys/map.h\"\n");
        fprintf(fp, "\n");
        fprintf(fp, "\n");
-       fprintf(fp, "#include \"../tahoevba/vbavar.h\"\n");
+       fprintf(fp, "#include \"tahoe/vba/vbavar.h\"\n");
        fprintf(fp, "\n");
        fprintf(fp, "#define C (caddr_t)\n\n");
        /*
        fprintf(fp, "\n");
        fprintf(fp, "#define C (caddr_t)\n\n");
        /*
@@ -445,30 +461,31 @@ tahoe_ioconf()
                    dp->d_flags);
        }
        fprintf(fp, "\t0\n};\n");
                    dp->d_flags);
        }
        fprintf(fp, "\t0\n};\n");
+       pseudo_ioconf(fp);
        (void) fclose(fp);
 }
 #endif
 
        (void) fclose(fp);
 }
 #endif
 
-#if MACHINE_HP300
+#if MACHINE_HP300 || MACHINE_LUNA68K
 hp300_ioconf()
 {
 hp300_ioconf()
 {
-       register struct device *dp, *mp, *np;
+       register struct device *dp, *mp;
        register int hpib, slave;
        FILE *fp;
        register int hpib, slave;
        FILE *fp;
-       extern char *wnum();
 
        fp = fopen(path("ioconf.c"), "w");
        if (fp == 0) {
                perror(path("ioconf.c"));
                exit(1);
        }
 
        fp = fopen(path("ioconf.c"), "w");
        if (fp == 0) {
                perror(path("ioconf.c"));
                exit(1);
        }
-       fprintf(fp, "#include \"machine/pte.h\"\n");
-       fprintf(fp, "#include \"../sys/param.h\"\n");
-       fprintf(fp, "#include \"../sys/buf.h\"\n");
-       fprintf(fp, "#include \"../sys/map.h\"\n");
-       fprintf(fp, "#include \"../sys/vm.h\"\n");
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "#include \"sys/map.h\"\n");
        fprintf(fp, "\n");
        fprintf(fp, "\n");
-       fprintf(fp, "#include \"../hpdev/device.h\"\n\n");
+       if (machine == MACHINE_HP300)
+               fprintf(fp, "#include \"hp/dev/device.h\"\n\n");
+       else
+               fprintf(fp, "#include \"luna68k/dev/device.h\"\n\n");
        fprintf(fp, "\n");
        fprintf(fp, "#define C (caddr_t)\n");
        fprintf(fp, "#define D (struct driver *)\n\n");
        fprintf(fp, "\n");
        fprintf(fp, "#define C (caddr_t)\n");
        fprintf(fp, "#define D (struct driver *)\n\n");
@@ -552,16 +569,16 @@ hp300_ioconf()
                        dp->d_addr, dp->d_dk, dp->d_flags);
        }
        fprintf(fp, "0\n};\n");
                        dp->d_addr, dp->d_dk, dp->d_flags);
        }
        fprintf(fp, "0\n};\n");
+       pseudo_ioconf(fp);
        (void) fclose(fp);
 }
 
 #define ishpibdev(n) (eq(n,"rd") || eq(n,"ct") || eq(n,"mt") || eq(n,"ppi"))
        (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"))
+#define isscsidev(n) (eq(n,"sd") || eq(n,"st") || eq(n,"ac"))
 
 hpbadslave(mp, dp)
        register struct device *dp, *mp;
 {
 
 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") &&
 
        if (mp == TO_NEXUS && ishpibdev(dp->d_name) ||
            mp != TO_NEXUS && eq(mp->d_name, "hpib") &&
@@ -579,18 +596,383 @@ hpbadslave(mp, dp)
        }
        return (0);
 }
        }
        return (0);
 }
+#endif
+
+#if MACHINE_I386
+char *sirq();
+
+i386_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, "/*\n");
+       fprintf(fp, " * ioconf.c \n");
+       fprintf(fp, " * Generated by config program\n");
+       fprintf(fp, " */\n\n");
+       fprintf(fp, "#include \"machine/pte.h\"\n");
+       fprintf(fp, "#include \"sys/param.h\"\n");
+       fprintf(fp, "#include \"sys/buf.h\"\n");
+       fprintf(fp, "#include \"sys/map.h\"\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#define V(s)       __CONCAT(V,s)\n");
+       fprintf(fp, "#define C (caddr_t)\n\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 ||
+                           !eq(mp->d_name, "isa"))
+                               continue;
+                       fprintf(fp,
+"extern struct isa_driver %sdriver; extern V(%s%d)();\n",
+                           dp->d_name, dp->d_name, dp->d_unit);
+               }
+               fprintf(fp, "\nstruct isa_device isa_devtab_bio[] = {\n");
+               fprintf(fp, "\
+/* driver      iobase  irq   drq     maddr    msiz    intr   unit */\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, "isa"))
+                               continue;
+                       if (!eq(dp->d_mask, "bio")) continue;
+                       if (dp->d_port)
+                fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
+                       else
+        fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
+               fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
+                               sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
+                        dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
+               }
+               fprintf(fp, "0\n};\n");
+
+               fprintf(fp, "struct isa_device isa_devtab_tty[] = {\n");
+               fprintf(fp, "\
+/* driver      iobase  irq   drq     maddr    msiz    intr   unit */\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, "isa"))
+                               continue;
+                       if (!eq(dp->d_mask, "tty")) continue;
+                       if (dp->d_port)
+                fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
+                       else
+        fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
+               fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
+                               sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
+                        dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
+               }
+               fprintf(fp, "0\n};\n\n");
+
+               fprintf(fp, "struct isa_device isa_devtab_net[] = {\n");
+               fprintf(fp, "\
+/* driver      iobase  irq   drq     maddr    msiz    intr   unit */\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, "isa"))
+                               continue;
+                       if (!eq(dp->d_mask, "net")) continue;
+                       if (dp->d_port)
+                fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
+                       else
+        fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
+               fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
+                               sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
+                        dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
+               }
+               fprintf(fp, "0\n};\n\n");
+
+               fprintf(fp, "struct isa_device isa_devtab_null[] = {\n");
+               fprintf(fp, "\
+/* driver      iobase  irq   drq     maddr    msiz    intr   unit */\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, "isa"))
+                               continue;
+                       if (!eq(dp->d_mask, "null")) continue;
+                       if (dp->d_port)
+                fprintf(fp, "{ &%sdriver,  %8.8s,", dp->d_name, dp->d_port);
+                       else
+        fprintf(fp, "{ &%sdriver,     0x%03x,", dp->d_name, dp->d_portn);
+               fprintf(fp, " %5.5s, %2d,  C 0x%05X, %5d, V(%s%d),  %2d },\n",
+                               sirq(dp->d_irq), dp->d_drq, dp->d_maddr,
+                        dp->d_msize, dp->d_name, dp->d_unit, dp->d_unit);
+               }
+               fprintf(fp, "0\n};\n\n");
+       }
+       pseudo_ioconf(fp);
+       (void) fclose(fp);
+}
 
 char *
 
 char *
-wnum(num)
+sirq(num)
 {
 
 {
 
-       if (num == QUES || num == UNKNOWN)
-               return ("?");
-       (void) sprintf(errbuf, "%d", num);
+       if (num == -1)
+               return ("0");
+       sprintf(errbuf, "IRQ%d", num);
        return (errbuf);
 }
 #endif
 
        return (errbuf);
 }
 #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, "#include \"sys/types.h\"\n");
+       fprintf(fp, "#include \"sys/time.h\"\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\tpri,\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,\t%d,\t0x%x },\n",
+                       dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri,
+                       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 (asc or sii) 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_ioconf(fp);
+       (void) fclose(fp);
+}
+#endif
+
+#if MACHINE_NEWS3400
+int have_iop = 0;
+int have_hb = 0;
+int have_vme = 0;
+
+news_ioconf()
+{
+       register struct device *dp, *mp;
+       register int 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 \"sys/buf.h\"\n");
+       fprintf(fp, "#include \"sys/map.h\"\n");
+       fprintf(fp, "#include \"vm/vm.h\"\n");
+       fprintf(fp, "#include \"iop.h\"\n");
+       fprintf(fp, "#include \"hb.h\"\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#if NIOP > 0\n");
+       fprintf(fp, "#include \"news3400/iop/iopvar.h\"\n");
+       fprintf(fp, "#endif\n");
+       fprintf(fp, "#if NHB > 0\n");
+       fprintf(fp, "#include \"news3400/hbdev/hbvar.h\"\n");
+       fprintf(fp, "#endif\n");
+       fprintf(fp, "\n");
+       fprintf(fp, "#define C (caddr_t)\n\n");
+       fprintf(fp, "\n");
+
+/* BEGIN HB */
+       fprintf(fp, "#if NHB > 0\n");
+       /*
+        * Now generate interrupt vectors for the HYPER-BUS
+        */
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               if (dp->d_pri >= 0) {
+                       mp = dp->d_conn;
+                       if (mp == 0 || mp == TO_NEXUS ||
+                           !eq(mp->d_name, "hb"))
+                               continue;
+                       fprintf(fp, "extern struct hb_driver %sdriver;\n",
+                           dp->d_name);
+                       have_hb++;
+               }
+       }
+       /*
+        * Now spew forth the hb_cinfo structure
+        */
+       fprintf(fp, "\nstruct hb_ctlr hminit[] = {\n");
+       fprintf(fp, "/*\t driver,\tctlr,\talive,\taddr,\tintpri */\n");
+       for (dp = dtab; dp != 0; dp = dp->d_next) {
+               mp = dp->d_conn;
+               if ((dp->d_type != MASTER && dp->d_type != CONTROLLER)
+                   || mp == TO_NEXUS || mp == 0 ||
+                   !eq(mp->d_name, "hb"))
+                       continue;
+               if (dp->d_pri < 0) {
+                       printf("must specify priority 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; ");
+                       printf("dont 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) don't have flags, ");
+                       printf("only devices do\n",
+                           dp->d_name, dp->d_unit);
+                       continue;
+               }
+               fprintf(fp, "\t{ &%sdriver,\t%d,\t0,\tC 0x%x,\t%d },\n",
+                   dp->d_name, dp->d_unit, dp->d_addr, dp->d_pri);
+       }
+       fprintf(fp, "\t0\n};\n");
+       /*
+        * Now we go for the hb_device stuff
+        */
+       fprintf(fp, "\nstruct hb_device hdinit[] = {\n");
+       fprintf(fp,
+"\t/* driver,  unit, ctlr,  slave,   addr,    pri,    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, "iop") || eq(mp->d_name, "vme"))
+                       continue;
+               if (eq(mp->d_name, "hb")) {
+                       if (dp->d_pri < 0) {
+                               printf("must specify vector 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 only ");
+                               printf("for controllers, not for device %s%d\n",
+                                   dp->d_name, dp->d_unit);
+                               continue;
+                       }
+                       slave = QUES;
+               } else {
+                       if (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;
+                       }
+                       if (dp->d_drive == UNKNOWN) {
+                               printf("must specify ``drive number'' for %s%d\n",
+                                  dp->d_name, dp->d_unit);
+                               continue;
+                       }
+                       /* NOTE THAT ON THE IOP ``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_pri >= 0) {
+                               printf("interrupt priority 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,    %2d,   C 0x%x, %d,  %d,  0x%x },\n",
+                   eq(mp->d_name, "hb") ? dp->d_name : mp->d_name, dp->d_unit,
+                   eq(mp->d_name, "hb") ? " -1" : qu(mp->d_unit),
+                   slave, dp->d_addr, dp->d_pri, dp->d_dk, dp->d_flags);
+       }
+       fprintf(fp, "\t0\n};\n\n");
+       fprintf(fp, "#endif\n\n");
+/* END HB */
+       pseudo_ioconf(fp);
+       (void) fclose(fp);
+}
+#endif
+
 char *
 intv(dev)
        register struct device *dev;
 char *
 intv(dev)
        register struct device *dev;
@@ -614,3 +996,89 @@ qu(num)
        (void) sprintf(errbuf, "%3d", num);
        return (errbuf);
 }
        (void) sprintf(errbuf, "%3d", num);
        return (errbuf);
 }
+
+char *
+wnum(num)
+{
+
+       if (num == QUES || num == UNKNOWN)
+               return ("?");
+       (void) sprintf(errbuf, "%d", num);
+       return (errbuf);
+}
+
+void
+pseudo_ioconf(fp)
+       register FILE *fp;
+{
+       register struct device *dp;
+
+       (void)fprintf(fp, "\n#include <sys/device.h>\n\n");
+       for (dp = dtab; dp != NULL; dp = dp->d_next)
+               if (dp->d_type == PSEUDO_DEVICE)
+                       (void)fprintf(fp, "extern void %sattach __P((int));\n",
+                           dp->d_name);
+       /*
+        * XXX concatonated disks are pseudo-devices but appear as DEVICEs
+        * since they don't adhere to normal pseudo-device conventions
+        * (i.e. one entry with total count in d_slave).
+        */
+       if (seen_cd)
+               (void)fprintf(fp, "extern void cdattach __P((int));\n");
+       /* XXX temporary for HP300, others */
+       (void)fprintf(fp, "\n#include <sys/systm.h> /* XXX */\n");
+       (void)fprintf(fp, "#define etherattach (void (*)__P((int)))nullop\n");
+       (void)fprintf(fp, "#define iteattach (void (*) __P((int)))nullop\n");
+       (void)fprintf(fp, "\nstruct pdevinit pdevinit[] = {\n");
+       for (dp = dtab; dp != NULL; dp = dp->d_next)
+               if (dp->d_type == PSEUDO_DEVICE)
+                       (void)fprintf(fp, "\t{ %sattach, %d },\n", dp->d_name,
+                           dp->d_slave > 0 ? dp->d_slave : 1);
+       /*
+        * XXX count up cds and put out an entry
+        */
+       if (seen_cd) {
+               struct file_list *fl;
+               int cdmax = -1;
+
+               for (fl = comp_list; fl != NULL; fl = fl->f_next)
+                       if (fl->f_type == COMPDEVICE && fl->f_compinfo > cdmax)
+                               cdmax = fl->f_compinfo;
+               (void)fprintf(fp, "\t{ cdattach, %d },\n", cdmax+1);
+       }
+       (void)fprintf(fp, "\t{ 0, 0 }\n};\n");
+       if (seen_cd)
+               comp_config(fp);
+}
+
+comp_config(fp)
+       FILE *fp;
+{
+       register struct file_list *fl;
+       register struct device *dp;
+
+       fprintf(fp, "\n#include \"dev/cdvar.h\"\n");
+       fprintf(fp, "\nstruct cddevice cddevice[] = {\n");
+       fprintf(fp, "/*\tunit\tileave\tflags\tdk\tdevs\t\t\t\t*/\n");
+
+       fl = comp_list;
+       while (fl) {
+               if (fl->f_type != COMPDEVICE) {
+                       fl = fl->f_next;
+                       continue;
+               }
+               for (dp = dtab; dp != 0; dp = dp->d_next)
+                       if (dp->d_type == DEVICE &&
+                           eq(dp->d_name, fl->f_fn) &&
+                           dp->d_unit == fl->f_compinfo)
+                               break;
+               if (dp == 0)
+                       continue;
+               fprintf(fp, "\t%d,\t%d,\t%d,\t%d,\t{",
+                       dp->d_unit, dp->d_pri, dp->d_flags, 1);
+               for (fl = fl->f_next; fl->f_type == COMPSPEC; fl = fl->f_next)
+                       fprintf(fp, " 0x%x,", fl->f_compdev);
+               fprintf(fp, " NODEV },\n");
+       }
+       fprintf(fp, "\t-1,\t0,\t0,\t0,\t{ 0 },\n};\n");
+}