Index: head/usr.sbin/config/config.y =================================================================== --- head/usr.sbin/config/config.y (revision 45720) +++ head/usr.sbin/config/config.y (revision 45721) @@ -1,1159 +1,1161 @@ %union { char *str; int val; struct file_list *file; struct idlst *lst; } %token AND %token ANY %token ARGS %token AT %token BIO %token BUS %token CAM %token HA %token COMMA %token CONFIG %token CONFLICTS %token CONTROLLER %token CPU %token CSR %token DEVICE %token DISABLE %token DISK %token DRIVE %token DRQ %token DUMPS %token EQUALS %token FLAGS %token IDENT %token INTERLEAVE %token IOMEM %token IOSIZ %token IRQ %token MACHINE %token MAJOR %token MASTER %token MAXUSERS %token MINOR %token MINUS %token NET %token NEXUS %token ON %token OPTIONS %token MAKEOPTIONS %token PORT %token PRIORITY %token PSEUDO_DEVICE %token ROOT %token SEMICOLON %token SEQUENTIAL %token SIZE %token SLAVE %token SWAP %token TARGET %token TTY %token TRACE %token UNIT %token VECTOR %token ID %token NUMBER %token FPNUMBER %type Save_id %type Opt_value %type Dev %type Id_list %type optional_size %type optional_sflag %type device_name %type major_minor %type arg_device_spec %type root_device_spec root_device_specs %type dump_device_spec %type swap_device_spec %type comp_device_spec %{ /* * Copyright (c) 1988, 1993 * 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. * * @(#)config.y 8.1 (Berkeley) 6/6/93 */ #include "config.h" #include #include #ifdef linux #include #endif #include #include #include #include struct device cur; struct device *curp = 0; #define ns(s) strdup(s) int alreadychecked __P((dev_t, dev_t[], dev_t *)); void deverror __P((char *, char *)); int finddev __P((dev_t)); void init_dev __P((struct device *)); void verifycomp __P((struct file_list *)); %} %% 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: MACHINE Save_id = { if (!strcmp($2, "vax")) { machine = MACHINE_VAX; machinename = "vax"; } else if (!strcmp($2, "tahoe")) { machine = MACHINE_TAHOE; machinename = "tahoe"; } else if (!strcmp($2, "hp300")) { machine = MACHINE_HP300; machinename = "hp300"; } else if (!strcmp($2, "i386")) { machine = MACHINE_I386; machinename = "i386"; } else if (!strcmp($2, "pc98")) { machine = MACHINE_PC98; machinename = "pc98"; } else if (!strcmp($2, "mips")) { machine = MACHINE_MIPS; machinename = "mips"; } else if (!strcmp($2, "pmax")) { machine = MACHINE_PMAX; machinename = "pmax"; } else if (!strcmp($2, "luna68k")) { machine = MACHINE_LUNA68K; machinename = "luna68k"; } else if (!strcmp($2, "news3400")) { machine = MACHINE_NEWS3400; machinename = "news3400"; } else if (!strcmp($2, "alpha")) { machine = MACHINE_ALPHA; machinename = "alpha"; } else yyerror("Unknown machine type"); } | CPU Save_id = { struct cputype *cp = (struct cputype *)malloc(sizeof (struct cputype)); memset(cp, 0, sizeof(*cp)); cp->cpu_name = $2; cp->cpu_next = cputype; cputype = cp; } | OPTIONS Opt_list | MAKEOPTIONS Mkopt_list | IDENT ID = { ident = $2; } | System_spec | 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 = { yyerror("swap specification obsolete, ignored"); } ; swap_device_list: swap_device_list AND swap_device | swap_device ; swap_device: swap_device_spec optional_size optional_sflag ; swap_device_spec: device_name = { struct file_list *fl = newflist(SWAPSPEC); if (eq($1, "generic")) fl->f_fn = $1; else { fl->f_swapdev = nametodev($1, 0, COMPATIBILITY_SLICE, 'b'); fl->f_fn = devtoname(fl->f_swapdev); } $$ = fl; } | major_minor = { struct file_list *fl = newflist(SWAPSPEC); fl->f_swapdev = $1; fl->f_fn = devtoname($1); $$ = fl; } ; root_spec: ROOT optional_on root_device_specs = { struct file_list *fl = *confp; if (fl && fl->f_rootdev != NODEV) yyerror("extraneous root device specification"); else fl->f_rootdev = $3; } ; root_device_specs: root_device_spec AND root_device_specs = { warnx("extraneous root devices ignored"); $$ = $1; } | root_device_spec ; root_device_spec: device_name = { $$ = nametodev($1, 0, COMPATIBILITY_SLICE, '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, COMPATIBILITY_SLICE, '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, COMPATIBILITY_SLICE, '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) snprintf(buf, 80, "%s%d", $1, $2); $$ = ns(buf); free($1); } | Save_id NUMBER ID = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s", $1, $2, $3); $$ = ns(buf); free($1); } | Save_id NUMBER ID NUMBER = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s%d", $1, $2, $3, $4); $$ = ns(buf); free($1); } | Save_id NUMBER ID NUMBER ID = { char buf[80]; (void) snprintf(buf, 80, "%s%d%s%d%s", $1, $2, $3, $4, $5); $$ = ns(buf); free($1); } ; Opt_list: Opt_list COMMA Option | Option ; Option: Save_id = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); char *s; memset(op, 0, sizeof(*op)); op->op_name = $1; op->op_next = opt; op->op_value = 0; /* * op->op_line is 1-based; yyline is 0-based but is now 1 * larger than when `Save_id' was lexed. */ op->op_line = yyline; opt = op; if ((s = strchr(op->op_name, '='))) { /* AARGH!!!! Old-style bogon */ *s = '\0'; op->op_value = ns(s + 1); } } | Save_id EQUALS Opt_value = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); memset(op, 0, sizeof(*op)); op->op_name = $1; op->op_next = opt; op->op_value = $3; op->op_line = yyline + 1; opt = op; } ; Opt_value: ID = { $$ = $1; } | NUMBER = { char nb[16]; (void) sprintf(nb, "%d", $1); $$ = ns(nb); } ; Save_id: ID = { $$ = $1; } ; Mkopt_list: Mkopt_list COMMA Mkoption | Mkoption ; Mkoption: Save_id EQUALS Opt_value = { struct opt *op = (struct opt *)malloc(sizeof (struct opt)); memset(op, 0, sizeof(*op)); op->op_name = $1; op->op_ownfile = 0; /* for now */ op->op_next = mkopt; op->op_value = $3; op->op_line = yyline + 1; mkopt = op; } ; Dev: ID = { $$ = $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; } | PSEUDO_DEVICE Dev_name Cdev_init Cdev_info = { if (!eq(cur.d_name, "cd")) yyerror("improper spec for pseudo-device"); seen_cd = 1; cur.d_type = DEVICE; verifycomp(*compp); }; Cdev_init: /* lambda */ = { mkcomp(&cur); }; Cdev_info: optional_on comp_device_list comp_option_list ; comp_device_list: comp_device_list AND comp_device | comp_device ; comp_device: comp_device_spec = { addcomp(*compp, $1); } ; comp_device_spec: device_name = { struct file_list *fl = newflist(COMPSPEC); fl->f_compdev = nametodev($1, 0, COMPATIBILITY_SLICE, 'c'); fl->f_fn = devtoname(fl->f_compdev); $$ = fl; } | major_minor = { struct file_list *fl = newflist(COMPSPEC); fl->f_compdev = $1; fl->f_fn = devtoname($1); $$ = fl; } ; comp_option_list: comp_option_list comp_option | /* lambda */ ; comp_option: INTERLEAVE NUMBER = { cur.d_pri = $2; } | FLAGS NUMBER = { cur.d_flags = $2; }; 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; else if (eq($2, "scbus")) seen_scbus = 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; }; Info_list: Info_list Info | /* lambda */ ; Info: CSR NUMBER = { cur.d_addr = $2; } | BUS NUMBER = { if (cur.d_conn != 0 && cur.d_conn->d_type == CONTROLLER) cur.d_slave = $2; else yyerror("can't specify a bus to something " "other than a controller"); } | TARGET NUMBER = { cur.d_target = $2; } | UNIT NUMBER = { cur.d_lun = $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 = $2; } | PORT NUMBER = { cur.d_portn = $2; } | TTY = { cur.d_mask = "tty"; } | BIO = { cur.d_mask = "bio"; } | CAM = { cur.d_mask = "cam"; } | HA = { cur.d_mask = "ha"; } | NET = { cur.d_mask = "net"; } | FLAGS NUMBER = { cur.d_flags = $2; } | DISABLE = { cur.d_disabled = 1; } | CONFLICTS = { cur.d_conflicts = 1; }; 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)); memset(a, 0, sizeof(*a)); a->id = $1; a->id_next = 0; $$ = a; } | Save_id Id_list = { struct idlst *a = (struct idlst *)malloc(sizeof(struct idlst)); memset(a, 0, sizeof(*a)); a->id = $1; a->id_next = $2; $$ = a; }; %% void yyerror(s) char *s; { warnx("line %d: %s", yyline + 1, s); } /* * add a device to the list of devices */ void newdev(dp) register struct device *dp; { register struct device *np; np = (struct device *) malloc(sizeof *np); memset(np, 0, 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 */ void mkconf(sysname) char *sysname; { register struct file_list *fl, **flp; fl = (struct file_list *) malloc(sizeof *fl); memset(fl, 0, sizeof(*fl)); fl->f_type = SYSTEMSPEC; fl->f_needs = 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)); memset(fl, 0, 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); } /* * Add a swap device to the system's configuration */ void mkswap(system, fl, size, flag) struct file_list *system, *fl; int size, flag; { register struct file_list **flp; 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; fl->f_swapflag = flag; /* * 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")) system->f_fn = ns(fl->f_fn); else system->f_fn = ns(system->f_needs); } void mkcomp(dp) register struct device *dp; { register struct file_list *fl, **flp; char buf[80]; fl = (struct file_list *) malloc(sizeof *fl); memset(fl, 0, sizeof(*fl)); 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 = ns(buf); fl->f_next = 0; for (flp = compp; *flp; flp = &(*flp)->f_next) ; *flp = fl; compp = flp; } void addcomp(compdev, fl) struct file_list *compdev, *fl; { register struct file_list **flp; 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); } void init_dev(dp) register struct device *dp; { dp->d_name = "OHNO!!!"; dp->d_type = DEVICE; dp->d_conn = 0; dp->d_conflicts = 0; dp->d_disabled = 0; dp->d_vec = 0; dp->d_addr = dp->d_flags = dp->d_dk = 0; dp->d_pri = -1; dp->d_slave = dp->d_lun = dp->d_target = dp->d_drive = dp->d_unit = UNKNOWN; dp->d_port = (char *)0; dp->d_portn = -1; dp->d_irq = -1; 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 */ void 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: case MACHINE_LUNA68K: if (num != QUES) dev->d_addr = num; break; case MACHINE_I386: case MACHINE_PC98: +#if 0 if (!eq(dev->d_name, "isa")) yyerror("only isa's should be connected to the nexus"); +#endif break; case MACHINE_NEWS3400: if (!eq(dev->d_name, "iop") && !eq(dev->d_name, "hb") && !eq(dev->d_name, "vme")) yyerror("only iop's, hb's and vme's should be connected to the nexus"); break; } } /* * Check system specification and apply defaulting * rules on root, argument, dump, and swap devices. */ void checksystemspec(fl) register struct file_list *fl; { char buf[BUFSIZ]; register struct file_list *swap; int generic; 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"); if (fl->f_rootdev == NODEV && !generic) { 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 = newflist(SWAPSPEC); dev = fl->f_rootdev; if (dkpart(dev) != 0) { (void) sprintf(buf, "Warning, swap defaulted to 'b' partition with root on '%c' partition", dkpart(dev) + 'a'); yyerror(buf); } swap->f_swapdev = dkmodpart(dev, SWAP_PART); 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; } /* * Warn if dump device is not a swap area. */ if (fl->f_dumpdev != NODEV && 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. */ void 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, "root"); *pchecked++ = fl->f_rootdev; pchecked = verifyswap(fl->f_next, checked, pchecked); if (!alreadychecked(fl->f_dumpdev, checked, pchecked)) { if (!finddev(fl->f_dumpdev)) deverror(fl->f_needs, "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")) continue; if (alreadychecked(fl->f_swapdev, checked, pchecked)) continue; if (!finddev(fl->f_swapdev)) warnx("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 */ void verifycomp(fl) register struct file_list *fl; { char *dname = fl->f_needs; for (fl = fl->f_next; fl; fl = fl->f_next) { if (fl->f_type != COMPSPEC || finddev(fl->f_compdev)) continue; warnx("%s: component device %s not configured", dname, fl->f_needs); } } /* * Has a device already been checked * for its existence in the configuration? */ int alreadychecked(dev, list, last) dev_t dev, list[]; register dev_t *last; { register dev_t *p; for (p = list; p < last; p++) if (dkmodpart(*p, 0) != dkmodpart(dev, 0)) return (1); return (0); } void deverror(systemname, devtype) char *systemname, *devtype; { warnx("%s: %s device not configured", systemname, devtype); } /* * Look for the device in the list of * configured hardware devices. Must * take into account stuff wildcarded. */ /*ARGSUSED*/ int finddev(dev) dev_t dev; { /* punt on this right now */ return (1); } Index: head/usr.sbin/config/configvers.h =================================================================== --- head/usr.sbin/config/configvers.h (revision 45720) +++ head/usr.sbin/config/configvers.h (revision 45721) @@ -1,11 +1,11 @@ /* * 6 digits of version. The most significant are branch indicators * (eg: RELENG_2_2 = 22, -current presently = 30 etc). The least * significant digits are incremented for each incompatable change. * * The numbering scheme is inspired by the sys/conf/newvers.sh RELDATE * and system. * - * $Id: configvers.h,v 1.10 1999/04/13 18:22:57 peter Exp $ + * $Id: configvers.h,v 1.11 1999/04/15 14:52:22 bde Exp $ */ -#define CONFIGVERS 300012 +#define CONFIGVERS 400013 Index: head/usr.sbin/config/mkioconf.c =================================================================== --- head/usr.sbin/config/mkioconf.c (revision 45720) +++ head/usr.sbin/config/mkioconf.c (revision 45721) @@ -1,1369 +1,1393 @@ /* * Copyright (c) 1980, 1993 * 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 #if 0 static char sccsid[] = "@(#)mkioconf.c 8.2 (Berkeley) 1/21/94"; #endif static const char rcsid[] = - "$Id: mkioconf.c,v 1.47 1999/02/05 16:49:18 bde Exp $"; + "$Id: mkioconf.c,v 1.48 1999/02/05 16:58:22 bde Exp $"; #endif /* not lint */ #include #include #include "y.tab.h" #include "config.h" /* * build the ioconf.c file */ char *qu(); char *intv(); char *wnum(); void pseudo_ioconf(); void comp_config __P((FILE *)); void scbus_devtab __P((FILE *, int *)); void isa_devtab __P((FILE *, char *, int *)); void isa_biotab __P((FILE *, char *)); void i386_ioconf __P((void)); void hp300_ioconf __P((void)); int hpbadslave __P((struct device *, struct device *)); void tahoe_ioconf __P((void)); void vax_ioconf __P((void)); +static char * +devstr(struct device *dp) +{ + static char buf[100]; + + if (dp == TO_NEXUS) + return "nexus0"; + + if (dp->d_unit >= 0) { + sprintf(buf, "%s%d", dp->d_name, dp->d_unit); + return buf; + } else + return dp->d_name; +} + +static void +write_device_resources(FILE *fp, struct device *dp) +{ + int count = 0; + + fprintf(fp, "struct config_resource %s_resources[] = {\n", devstr(dp)); + if (dp->d_conn) { + fprintf(fp, "\t{ \"at\",\tRES_STRING,\t{ (long)\"%s\" }},\n", + devstr(dp->d_conn)); + count++; + } + if (dp->d_drive != -2) { + fprintf(fp, "\t{ \"drive\",\tRES_INT,\t{ %d }},\n", dp->d_drive); + count++; + } + if (dp->d_target != -2) { + fprintf(fp, "\t{ \"target\",\tRES_INT,\t{ %d }},\n", dp->d_target); + count++; + } + if (dp->d_lun != -2) { + fprintf(fp, "\t{ \"lun\",\tRES_INT,\t{ %d }},\n", dp->d_lun); + count++; + } + if (dp->d_flags) { + fprintf(fp, "\t{ \"flags\",\tRES_INT,\t{ 0x%x }},\n", dp->d_flags); + count++; + } + if (dp->d_conflicts) { + fprintf(fp, "\t{ \"conflicts\",\tRES_INT,\t{ %d }},\n", dp->d_conflicts); + count++; + } + if (dp->d_disabled) { + fprintf(fp, "\t{ \"disabled\",\tRES_INT,\t{ %d }},\n", dp->d_disabled); + count++; + } + if (dp->d_port) { + fprintf(fp, "\t{ \"port\",\tRES_INT,\t { %s }},\n", dp->d_port); + count++; + } + if (dp->d_portn > 0) { + fprintf(fp, "\t{ \"port\",\tRES_INT,\t{ 0x%x }},\n", dp->d_portn); + count++; + } + if (dp->d_maddr > 0) { + fprintf(fp, "\t{ \"maddr\",\tRES_INT,\t{ 0x%x }},\n", dp->d_maddr); + count++; + } + if (dp->d_msize > 0) { + fprintf(fp, "\t{ \"msize\",\tRES_INT,\t{ 0x%x }},\n", dp->d_msize); + count++; + } + if (dp->d_drq > 0) { + fprintf(fp, "\t{ \"drq\",\tRES_INT,\t{ %d }},\n", dp->d_drq); + count++; + } + if (dp->d_irq > 0) { + fprintf(fp, "\t{ \"irq\",\tRES_INT,\t{ %d }},\n", dp->d_irq); + count++; + } + fprintf(fp, "};\n"); + fprintf(fp, "#define %s_count %d\n", devstr(dp), count); +} + +static void +write_all_device_resources(FILE *fp) +{ + struct device *dp; + + for (dp = dtab; dp != 0; dp = dp->d_next) { + if (dp->d_type != CONTROLLER && dp->d_type != MASTER + && dp->d_type != DEVICE) + continue; + write_device_resources(fp, dp); + } +} + +static void +write_devtab(FILE *fp) +{ + struct device *dp; + int count; + + write_all_device_resources(fp); + + count = 0; + fprintf(fp, "struct config_device config_devtab[] = {\n"); + for (dp = dtab; dp != 0; dp = dp->d_next) { + char* n = devstr(dp); + if (dp->d_type != CONTROLLER && dp->d_type != MASTER + && dp->d_type != DEVICE) + continue; + fprintf(fp, "\t{ \"%s\",\t%d,\t%s_count,\t%s_resources },\n", + dp->d_name, dp->d_unit, n, n); + count++; + } + fprintf(fp, "};\n"); + fprintf(fp, "int devtab_count = %d;\n", count); +} + #if MACHINE_VAX void vax_ioconf() { register struct device *dp, *mp, *np; register int uba_n, slave; FILE *fp; fp = fopen(path("ioconf.c"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \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_ioconf(fp); (void) fclose(fp); } #endif #if MACHINE_TAHOE void tahoe_ioconf() { register struct device *dp, *mp, *np; register int vba_n, slave; FILE *fp; fp = fopen(path("ioconf.c"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); fprintf(fp, "#include \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_ioconf(fp); (void) fclose(fp); } #endif #if MACHINE_HP300 || MACHINE_LUNA68K void hp300_ioconf() { register struct device *dp, *mp; register int hpib, slave; FILE *fp; fp = fopen(path("ioconf.c"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); if (machine == MACHINE_HP300) fprintf(fp, "#include \n\n"); else fprintf(fp, "#include \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_ioconf(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") || eq(n,"ac")) int hpbadslave(mp, dp) register struct device *dp, *mp; { 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); } #endif #if MACHINE_I386 char *sirq(); void i386_ioconf() { register struct device *dp, *mp; int dev_id; FILE *fp; static char *old_d_name; int count; fp = fopen(path("ioconf.c.new"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c.new")); fprintf(fp, "/*\n"); fprintf(fp, " * I/O configuration.\n"); fprintf(fp, " * DO NOT EDIT-- this file is automatically generated.\n"); fprintf(fp, " */\n"); fprintf(fp, "\n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); fprintf(fp, "#define C (caddr_t)\n"); + +#if 0 /* * First print the isa initialization structures */ if (seen_isa) { int seen_wdc = 0, seen_fdc = 0; fprintf(fp, "\n"); fprintf(fp, "/*\n"); fprintf(fp, " * ISA devices.\n"); fprintf(fp, " */\n"); fprintf(fp, "\n"); fprintf(fp, "#include \n"); if (machine == MACHINE_I386) fprintf(fp, "#include \n"); else fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "\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; if (old_d_name == NULL || !eq(dp->d_name, old_d_name)) { old_d_name = dp->d_name; fprintf(fp, "extern struct isa_driver %3sdriver;\n", old_d_name); } if (eq(dp->d_name, "wdc")) seen_wdc++; if (eq(dp->d_name, "fdc")) seen_fdc++; if ((dp->d_irq == 2) && (machine == MACHINE_I386)) { fprintf(stderr, "remapped irq 2 to irq 9, please update your config file\n"); dp->d_irq = 9; } } dev_id = 10; /* XXX must match mkglue.c */ isa_devtab(fp, "bio", &dev_id); if (seen_wdc) isa_biotab(fp, "wdc"); if (seen_fdc) isa_biotab(fp, "fdc"); isa_devtab(fp, "tty", &dev_id); isa_devtab(fp, "net", &dev_id); isa_devtab(fp, "cam", &dev_id); isa_devtab(fp, "ha", &dev_id); isa_devtab(fp, "null", &dev_id); } +#endif + if (seen_scbus) scbus_devtab(fp, &dev_id); fprintf(fp, "\n"); fprintf(fp, "/*\n"); fprintf(fp, " * New bus architecture devices.\n"); fprintf(fp, " */\n"); fprintf(fp, "\n"); fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); + fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); - count = 0; - fprintf(fp, "struct config_device devtab[] = {\n"); - fprintf(fp, "/* name, unit, resource count, resources */\n"); - fprintf(fp, "{ 0, 0, 0, 0 }\n"); - fprintf(fp, "};\n"); - fprintf(fp, "\n"); - fprintf(fp, "int devtab_count = %d;\n", count); + write_devtab(fp); + (void) fclose(fp); moveifchanged(path("ioconf.c.new"), path("ioconf.c")); } void isa_biotab(fp, table) FILE *fp; char *table; { register struct device *dp, *mp; fprintf(fp, "\n"); fprintf(fp, "struct isa_device isa_biotab_%s[] = {\n", table); fprintf(fp, "\ /* id driver iobase irq drq maddr msiz intr unit flags drive alive ri_flags reconfig enabled conflicts next */\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, table)) continue; fprintf(fp, "{ -1, &%3sdriver, ", mp->d_name); if (mp->d_port) fprintf(fp, " %8s,", mp->d_port); else if (mp->d_portn == -1) fprintf(fp, " %d,", mp->d_portn); else fprintf(fp, " 0x%04x,", mp->d_portn); fprintf(fp, "%6s, %2d, C 0x%05X, %5d, {0}, %3d, 0x%04X, %5d, 0, 0, 0, %6d, %8d, 0 },\n", sirq(mp->d_irq), mp->d_drq, mp->d_maddr, mp->d_msize, dp->d_unit, dp->d_flags, dp->d_drive, !dp->d_disabled, dp->d_conflicts); } fprintf(fp, "{ 0 }\n};\n"); } /* * Generized routine for isa bus device table, instead of repeating * all this 4 times, call this with the table argument. * * 4/26/93 rgrimes */ void isa_devtab(fp, table, dev_idp) FILE *fp; char *table; int *dev_idp; { register struct device *dp, *mp; fprintf(fp, "\n"); fprintf(fp, "struct isa_device isa_devtab_%s[] = {\n", table); fprintf(fp, "\ /* id driver iobase irq drq maddr msiz intr unit flags scsiid alive ri_flags reconfig enabled conflicts next */\n"); for (dp = dtab; dp != 0; dp = dp->d_next) { if (dp->d_unit == QUES || !eq(dp->d_mask, table)) continue; mp = dp->d_conn; if (mp == NULL || mp == TO_NEXUS || !eq(mp->d_name, "isa")) continue; fprintf(fp, "{ %2d, &%3sdriver,", (*dev_idp)++, dp->d_name); if (dp->d_port) fprintf(fp, " %8s,", dp->d_port); else if (dp->d_portn == -1) fprintf(fp, " %d,", dp->d_portn); else fprintf(fp, " 0x%04x,", dp->d_portn); fprintf(fp, "%6s, %2d, C 0x%05X, %5d, {0}, %3d, 0x%04X, 0, 0, 0, 0, %6d, %8d, 0 },\n", sirq(dp->d_irq), dp->d_drq, dp->d_maddr, dp->d_msize, dp->d_unit, dp->d_flags, !dp->d_disabled, dp->d_conflicts); } fprintf(fp, "{ 0 }\n};\n"); } static char * id(int unit) { char *s; switch(unit) { case UNKNOWN: s ="CAMCONF_UNSPEC"; break;; case QUES: s ="CAMCONF_ANY"; break; default: s = qu(unit); } return s; } static void id_put(fp, unit, s) FILE *fp; int unit; char *s; { fprintf(fp, "%s%s", id(unit), s); } /* XXX: dufault@hda.com: wiped out mkioconf.c locally: * All that nice "conflicting SCSI ID checking" is now * lost and should be put back in. */ void scbus_devtab(fp, dev_idp) FILE *fp; int *dev_idp; { register struct device *dp, *mp; fprintf(fp, "\n"); fprintf(fp, "/*\n"); fprintf(fp, " * CAM devices.\n"); fprintf(fp, " */\n"); fprintf(fp, "\n"); fprintf(fp, "#include \n"); fprintf(fp, "\n"); fprintf(fp, "struct cam_sim_config cam_sinit[] = {\n"); fprintf(fp, "/* pathid, sim name, sim unit, sim bus */\n"); /* XXX: Why do we always get an entry such as: * { '?', "ncr", '?', '?' }, */ for (dp = dtab; dp; dp = dp->d_next) { mp = dp->d_conn; if (dp->d_type != CONTROLLER || mp == TO_NEXUS || mp == 0 || !eq(dp->d_name, "scbus")) { continue; } fprintf(fp, "{ %s, ", id(dp->d_unit)); fprintf(fp, "\"%s\", ", mp->d_name); fprintf(fp, "%s, ", id(mp->d_unit)); fprintf(fp, "%s },\n", id(dp->d_slave)); } fprintf(fp, "{ 0, 0, 0, 0 }\n"); fprintf(fp, "};\n"); fprintf(fp, "\n"); fprintf(fp, "struct cam_periph_config cam_pinit[] = {\n"); fprintf(fp, "/* periph name, periph unit, pathid, target, LUN, flags */\n"); for (dp = dtab; dp; dp = dp->d_next) { if (dp->d_type == CONTROLLER || dp->d_type == MASTER || - dp->d_type == PSEUDO_DEVICE) + dp->d_type == PSEUDO_DEVICE + || dp->d_conn == TO_NEXUS) continue; mp = dp->d_conn; if (mp == 0 || !eq(mp->d_name, "scbus")) { continue; } if (mp->d_conn == 0 && (dp->d_target != UNKNOWN && dp->d_target != QUES)) { fprintf(stderr, "Warning: %s%s is configured at ", dp->d_name, wnum(dp->d_unit)); fprintf(stderr, "%s%s which is not fixed at a single adapter.\n", mp->d_name, wnum(mp->d_unit)); } fprintf(fp, "{ "); fprintf(fp, "\"%s\", ", dp->d_name); id_put(fp, dp->d_unit, ", "); id_put(fp, mp->d_unit, ", "); id_put(fp, dp->d_target, ", "); id_put(fp, dp->d_lun, ", "); fprintf(fp, " 0x%x },\n", dp->d_flags); } fprintf(fp, "{ 0, 0, 0, 0, 0, 0 }\n"); fprintf(fp, "};\n"); } /* * XXX - there should be a general function to print devtabs instead of these * little pieces of it. */ char * sirq(num) { if (num == -1) return ("0"); sprintf(errbuf, "IRQ%d", num); return (errbuf); } #endif #if MACHINE_PMAX void pmax_ioconf() { register struct device *dp, *mp; FILE *fp; fp = fopen(path("ioconf.c"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \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; void news_ioconf() { register struct device *dp, *mp; register int slave; FILE *fp; fp = fopen(path("ioconf.c"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \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 \n"); fprintf(fp, "#endif\n"); fprintf(fp, "#if NHB > 0\n"); fprintf(fp, "#include \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, 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 #if MACHINE_ALPHA -static char * -devstr(struct device *dp) -{ - static char buf[100]; - - if (dp->d_unit >= 0) { - sprintf(buf, "%s%d", dp->d_name, dp->d_unit); - return buf; - } else - return dp->d_name; -} - -static void -write_device_resources(FILE *fp, struct device *dp) -{ - int count = 0; - - fprintf(fp, "struct config_resource %s_resources[] = {\n", devstr(dp)); - if (dp->d_conn) { - fprintf(fp, "\t\"at\",\tRES_STRING,\t(long)\"%s\",\n", - devstr(dp->d_conn)); - count++; - } - if (dp->d_drive != -2) { - fprintf(fp, "\t\"drive\",\tRES_INT,\t%d,\n", dp->d_drive); - count++; - } - if (dp->d_target != -2) { - fprintf(fp, "\t\"target\",\tRES_INT,\t%d,\n", dp->d_target); - count++; - } - if (dp->d_lun != -2) { - fprintf(fp, "\t\"lun\",\tRES_INT,\t%d,\n", dp->d_lun); - count++; - } - if (dp->d_flags) { - fprintf(fp, "\t\"flags\",\tRES_INT,\t0x%x,\n", dp->d_flags); - count++; - } - if (dp->d_conflicts) { - fprintf(fp, "\t\"conflicts\",\tRES_INT,\t%d,\n", dp->d_conflicts); - count++; - } - if (dp->d_disabled) { - fprintf(fp, "\t\"disabled\",\tRES_INT,\t%d,\n", dp->d_disabled); - count++; - } - if (dp->d_port) { - fprintf(fp, "\t\"port\",\tRES_INT,\t%s,\n", dp->d_port); - count++; - } - if (dp->d_portn > 0) { - fprintf(fp, "\t\"port\",\tRES_INT,\t0x%x,\n", dp->d_portn); - count++; - } - if (dp->d_maddr > 0) { - fprintf(fp, "\t\"maddr\",\tRES_INT,\t0x%x,\n", dp->d_maddr); - count++; - } - if (dp->d_msize > 0) { - fprintf(fp, "\t\"msize\",\tRES_INT,\t0x%x,\n", dp->d_msize); - count++; - } - if (dp->d_drq > 0) { - fprintf(fp, "\t\"drq\",\tRES_INT,\t%d,\n", dp->d_drq); - count++; - } - if (dp->d_irq > 0) { - fprintf(fp, "\t\"irq\",\tRES_INT,\t%d,\n", dp->d_irq); - count++; - } - fprintf(fp, "};\n"); - fprintf(fp, "#define %s_count %d\n", devstr(dp), count); -} - void alpha_ioconf() { register struct device *dp, *mp; FILE *fp; int dev_id = 10; int count; fp = fopen(path("ioconf.c.new"), "w"); if (fp == 0) err(1, "%s", path("ioconf.c")); fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n\n"); + fprintf(fp, "#include \n"); fprintf(fp, "#include \n"); fprintf(fp, "#include \n\n"); fprintf(fp, "#define C (char *)\n\n"); - for (dp = dtab; dp != 0; dp = dp->d_next) { - if (dp->d_type != CONTROLLER && dp->d_type != MASTER - && dp->d_type != DEVICE) - continue; - write_device_resources(fp, dp); - } - count = 0; - fprintf(fp, "struct config_device devtab[] = {\n"); - for (dp = dtab; dp != 0; dp = dp->d_next) { - char* n = devstr(dp); - if (dp->d_type != CONTROLLER && dp->d_type != MASTER - && dp->d_type != DEVICE) - continue; - fprintf(fp, "\t\"%s\",\t%d,\t%s_count,\t%s_resources,\n", - dp->d_name, dp->d_unit, n, n); - count++; - } - fprintf(fp, "};\n"); - fprintf(fp, "int devtab_count = %d;\n", count); + write_devtab(fp); if (seen_scbus) scbus_devtab(fp, &dev_id); (void) fclose(fp); moveifchanged(path("ioconf.c.new"), path("ioconf.c")); } #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); } 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 \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 /* 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); } void comp_config(fp) FILE *fp; { register struct file_list *fl; register struct device *dp; fprintf(fp, "\n#include \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 < 0 ? 0 : 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"); }