[BACK]Return to autoconf.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / i386 / i386

Annotation of src/sys/arch/i386/i386/autoconf.c, Revision 1.44

1.44    ! drochner    1: /*     $NetBSD: autoconf.c,v 1.43 1999/10/25 17:26:07 drochner Exp $   */
1.11      cgd         2:
1.1       cgd         3: /*-
                      4:  * Copyright (c) 1990 The Regents of the University of California.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * William Jolitz.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the University of
                     21:  *     California, Berkeley and its contributors.
                     22:  * 4. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  *
1.11      cgd        38:  *     @(#)autoconf.c  7.1 (Berkeley) 5/9/91
1.1       cgd        39:  */
                     40:
                     41: /*
                     42:  * Setup the system to run on the current machine.
                     43:  *
                     44:  * Configure() is called at boot time and initializes the vba
                     45:  * device tables and the memory controller monitoring.  Available
                     46:  * devices are determined (from possibilities mentioned in ioconf.c),
                     47:  * and the drivers are initialized.
                     48:  */
1.43      drochner   49:
                     50: #include "opt_compat_oldboot.h"
                     51:
1.9       mycroft    52: #include <sys/param.h>
                     53: #include <sys/systm.h>
                     54: #include <sys/buf.h>
                     55: #include <sys/dkstat.h>
                     56: #include <sys/disklabel.h>
                     57: #include <sys/conf.h>
1.43      drochner   58: #ifdef COMPAT_OLDBOOT
1.9       mycroft    59: #include <sys/reboot.h>
1.43      drochner   60: #endif
1.13      mycroft    61: #include <sys/device.h>
1.34      fvdl       62: #include <sys/malloc.h>
1.25      drochner   63: #include <sys/vnode.h>
                     64: #include <sys/fcntl.h>
                     65: #include <sys/dkio.h>
1.1       cgd        66:
1.9       mycroft    67: #include <machine/pte.h>
1.20      christos   68: #include <machine/cpu.h>
1.25      drochner   69: #include <machine/bootinfo.h>
1.1       cgd        70:
1.28      drochner   71: static int match_harddisk __P((struct device *, struct btinfo_bootdisk *));
1.32      fvdl       72: static void matchbiosdisks __P((void));
1.23      thorpej    73: void findroot __P((struct device **, int *));
1.19      mycroft    74:
1.35      fvdl       75: extern struct disklist *i386_alldisks;
                     76: extern int i386_ndisks;
1.34      fvdl       77:
1.1       cgd        78: /*
                     79:  * Determine i/o configuration for a machine.
                     80:  */
1.19      mycroft    81: void
1.40      thorpej    82: cpu_configure()
1.1       cgd        83: {
                     84:
1.12      mycroft    85:        startrtclock();
                     86:
1.18      cgd        87:        if (config_rootfound("mainbus", NULL) == NULL)
                     88:                panic("configure: mainbus not configured");
1.12      mycroft    89:
1.22      christos   90:        printf("biomask %x netmask %x ttymask %x\n",
1.12      mycroft    91:            (u_short)imask[IPL_BIO], (u_short)imask[IPL_NET],
                     92:            (u_short)imask[IPL_TTY]);
                     93:
                     94:        spl0();
1.37      thorpej    95:
                     96:        /* Set up proc0's TSS and LDT (after the FPU is configured). */
                     97:        i386_proc0_tss_ldt_init();
1.30      thorpej    98:
                     99:        /* XXX Finish deferred buffer cache allocation. */
                    100:        i386_bufinit();
1.24      gwr       101: }
1.28      drochner  102:
1.24      gwr       103: void
                    104: cpu_rootconf()
                    105: {
                    106:        struct device *booted_device;
                    107:        int booted_partition;
1.1       cgd       108:
1.23      thorpej   109:        findroot(&booted_device, &booted_partition);
1.32      fvdl      110:        matchbiosdisks();
1.23      thorpej   111:
                    112:        printf("boot device: %s\n",
                    113:            booted_device ? booted_device->dv_xname : "<unknown>");
                    114:
1.38      thorpej   115:        setroot(booted_device, booted_partition);
1.1       cgd       116: }
                    117:
1.34      fvdl      118: /*
                    119:  * XXX ugly bit of code. But, this is the only safe time that the
                    120:  * match between BIOS disks and native disks can be done.
                    121:  */
1.32      fvdl      122: static void
                    123: matchbiosdisks()
                    124: {
                    125:        struct btinfo_biosgeom *big;
                    126:        struct bi_biosgeom_entry *be;
                    127:        struct device *dv;
                    128:        struct devnametobdevmaj *d;
1.34      fvdl      129:        int i, ck, error, m, n;
1.32      fvdl      130:        struct vnode *tv;
1.34      fvdl      131:        char mbr[DEV_BSIZE];
1.32      fvdl      132:
                    133:        big = lookup_bootinfo(BTINFO_BIOSGEOM);
                    134:
1.36      fvdl      135:        if (big == NULL)
1.32      fvdl      136:                return;
                    137:
1.34      fvdl      138:        /*
                    139:         * First, count all native disks
                    140:         */
                    141:        for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next)
                    142:                if (dv->dv_class == DV_DISK &&
                    143:                    (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
                    144:                     !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd")))
1.35      fvdl      145:                        i386_ndisks++;
                    146:
                    147:        if (i386_ndisks == 0)
                    148:                return;
1.34      fvdl      149:
                    150:        /* XXX M_TEMP is wrong */
1.35      fvdl      151:        i386_alldisks = malloc(sizeof (struct disklist) + (i386_ndisks - 1) *
                    152:                                sizeof (struct nativedisk_info),
                    153:                                M_TEMP, M_NOWAIT);
                    154:        if (i386_alldisks == NULL)
1.34      fvdl      155:                return;
                    156:
1.35      fvdl      157:        i386_alldisks->dl_nnativedisks = i386_ndisks;
                    158:        i386_alldisks->dl_nbiosdisks = big->num;
                    159:        for (i = 0; i < big->num; i++) {
                    160:                i386_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
                    161:                i386_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
                    162:                i386_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
                    163:                i386_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
                    164:                i386_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
                    165:                i386_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
                    166:        }
                    167:
1.34      fvdl      168:        /*
                    169:         * XXX code duplication from findroot()
                    170:         */
                    171:        n = -1;
1.32      fvdl      172:        for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
                    173:                if (dv->dv_class != DV_DISK)
                    174:                        continue;
                    175: #ifdef GEOM_DEBUG
                    176:                printf("matchbiosdisks: trying to match (%s) %s\n",
                    177:                    dv->dv_xname, dv->dv_cfdata->cf_driver->cd_name);
                    178: #endif
                    179:                if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
                    180:                    !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd")) {
1.34      fvdl      181:                        n++;
1.35      fvdl      182:                        sprintf(i386_alldisks->dl_nativedisks[n].ni_devname,
                    183:                            "%s%d", dv->dv_cfdata->cf_driver->cd_name,
1.34      fvdl      184:                            dv->dv_unit);
                    185:
1.38      thorpej   186:                        for (d = dev_name2blk; d->d_name &&
1.32      fvdl      187:                           strcmp(d->d_name, dv->dv_cfdata->cf_driver->cd_name);
                    188:                           d++);
                    189:                        if (d->d_name == NULL)
                    190:                                return;
1.34      fvdl      191:
1.32      fvdl      192:                        if (bdevvp(MAKEDISKDEV(d->d_maj, dv->dv_unit, RAW_PART),
                    193:                            &tv))
                    194:                                panic("matchbiosdisks: can't alloc vnode");
1.34      fvdl      195:
1.33      fvdl      196:                        error = VOP_OPEN(tv, FREAD, NOCRED, 0);
                    197:                        if (error) {
1.42      fvdl      198:                                vput(tv);
1.33      fvdl      199:                                continue;
                    200:                        }
1.34      fvdl      201:                        error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
                    202:                            UIO_SYSSPACE, 0, NOCRED, NULL, 0);
                    203:                        VOP_CLOSE(tv, FREAD, NOCRED, 0);
                    204:                        if (error) {
1.32      fvdl      205: #ifdef GEOM_DEBUG
                    206:                                printf("matchbiosdisks: %s: MBR read failure\n",
                    207:                                    dv->dv_xname);
                    208: #endif
                    209:                                continue;
                    210:                        }
1.34      fvdl      211:
1.32      fvdl      212:                        for (ck = i = 0; i < DEV_BSIZE; i++)
                    213:                                ck += mbr[i];
1.34      fvdl      214:                        for (m = i = 0; i < big->num; i++) {
1.32      fvdl      215:                                be = &big->disk[i];
                    216: #ifdef GEOM_DEBUG
                    217:                                printf("match %s with %d\n", dv->dv_xname, i);
                    218:                                printf("dev ck %x bios ck %x\n", ck, be->cksum);
                    219: #endif
                    220:                                if (be->flags & BI_GEOM_INVALID)
                    221:                                        continue;
                    222:                                if (be->cksum == ck &&
                    223:                                    !memcmp(&mbr[MBR_PARTOFF], be->dosparts,
                    224:                                        NMBRPART *
                    225:                                            sizeof (struct mbr_partition))) {
                    226: #ifdef GEOM_DEBUG
                    227:                                        printf("matched bios disk %x with %s\n",
                    228:                                            be->dev, be->devname);
                    229: #endif
1.35      fvdl      230:                                        i386_alldisks->dl_nativedisks[n].
                    231:                                            ni_biosmatches[m++] = i;
1.32      fvdl      232:                                }
                    233:                        }
1.35      fvdl      234:                        i386_alldisks->dl_nativedisks[n].ni_nmatches = m;
1.42      fvdl      235:                        vput(tv);
1.32      fvdl      236:                }
                    237:        }
                    238: }
                    239:
1.43      drochner  240: #ifdef COMPAT_OLDBOOT
1.1       cgd       241: u_long bootdev = 0;            /* should be dev_t, but not until 32 bits */
1.43      drochner  242: #endif
1.25      drochner  243: struct device *booted_device;
1.1       cgd       244:
                    245: /*
1.28      drochner  246:  * helper function for "findroot()":
                    247:  * return nonzero if disk device matches bootinfo
                    248:  */
1.32      fvdl      249: static int
                    250: match_harddisk(dv, bid)
1.28      drochner  251:        struct device *dv;
                    252:        struct btinfo_bootdisk *bid;
                    253: {
                    254:        struct devnametobdevmaj *i;
                    255:        struct vnode *tmpvn;
                    256:        int error;
                    257:        struct disklabel label;
                    258:        int found = 0;
                    259:
                    260:        /*
                    261:         * A disklabel is required here.  The
                    262:         * bootblocks don't refuse to boot from
                    263:         * a disk without a label, but this is
                    264:         * normally not wanted.
                    265:         */
                    266:        if (bid->labelsector == -1)
                    267:                return(0);
                    268:
                    269:        /*
                    270:         * lookup major number for disk block device
                    271:         */
1.38      thorpej   272:        i = dev_name2blk;
1.28      drochner  273:        while (i->d_name &&
                    274:               strcmp(i->d_name, dv->dv_cfdata->cf_driver->cd_name))
                    275:                i++;
                    276:        if (i->d_name == NULL)
                    277:                return(0); /* XXX panic() ??? */
                    278:
                    279:        /*
                    280:         * Fake a temporary vnode for the disk, open
                    281:         * it, and read the disklabel for comparison.
                    282:         */
                    283:        if (bdevvp(MAKEDISKDEV(i->d_maj, dv->dv_unit, bid->partition), &tmpvn))
                    284:                panic("findroot can't alloc vnode");
                    285:        error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
                    286:        if (error) {
                    287: #ifndef DEBUG
1.31      bouyer    288:                /*
                    289:                 * Ignore errors caused by missing
                    290:                 * device, partition or medium.
                    291:                 */
                    292:                if (error != ENXIO && error != ENODEV)
1.28      drochner  293: #endif
                    294:                        printf("findroot: can't open dev %s%c (%d)\n",
                    295:                               dv->dv_xname, 'a' + bid->partition, error);
1.42      fvdl      296:                vput(tmpvn);
1.28      drochner  297:                return(0);
                    298:        }
                    299:        error = VOP_IOCTL(tmpvn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 0);
                    300:        if (error) {
                    301:                /*
                    302:                 * XXX can't happen - open() would
                    303:                 * have errored out (or faked up one)
                    304:                 */
                    305:                printf("can't get label for dev %s%c (%d)\n",
                    306:                       dv->dv_xname, 'a' + bid->partition, error);
                    307:                goto closeout;
                    308:        }
                    309:
                    310:        /* compare with our data */
                    311:        if (label.d_type == bid->label.type &&
                    312:            label.d_checksum == bid->label.checksum &&
                    313:            !strncmp(label.d_packname, bid->label.packname, 16))
                    314:                found = 1;
                    315:
                    316: closeout:
                    317:        VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
1.42      fvdl      318:        vput(tmpvn);
1.28      drochner  319:        return(found);
                    320: }
                    321:
                    322: /*
1.1       cgd       323:  * Attempt to find the device from which we were booted.
                    324:  * If we can do so, and not instructed not to do so,
                    325:  * change rootdev to correspond to the load device.
                    326:  */
1.19      mycroft   327: void
1.23      thorpej   328: findroot(devpp, partp)
                    329:        struct device **devpp;
                    330:        int *partp;
1.1       cgd       331: {
1.25      drochner  332:        struct btinfo_bootdisk *bid;
                    333:        struct device *dv;
1.43      drochner  334: #ifdef COMPAT_OLDBOOT
1.23      thorpej   335:        int i, majdev, unit, part;
                    336:        char buf[32];
1.43      drochner  337: #endif
1.23      thorpej   338:
                    339:        /*
                    340:         * Default to "not found."
                    341:         */
                    342:        *devpp = NULL;
                    343:        *partp = 0;
1.1       cgd       344:
1.26      thorpej   345:        if (booted_device) {
1.25      drochner  346:                *devpp = booted_device;
                    347:                return;
                    348:        }
1.26      thorpej   349:        if (lookup_bootinfo(BTINFO_NETIF)) {
1.25      drochner  350:                /*
                    351:                 * We got netboot interface information, but
                    352:                 * "device_register()" couldn't match it to a configured
                    353:                 * device. Bootdisk information cannot be present at the
                    354:                 * same time, so give up.
                    355:                 */
                    356:                printf("findroot: netboot interface not found\n");
                    357:                return;
                    358:        }
                    359:
                    360:        bid = lookup_bootinfo(BTINFO_BOOTDISK);
1.26      thorpej   361:        if (bid) {
1.25      drochner  362:                /*
                    363:                 * Scan all disk devices for ones that match the passed data.
                    364:                 * Don't break if one is found, to get possible multiple
                    365:                 * matches - for problem tracking. Use the first match anyway
                    366:                 * because lower device numbers are more likely to be the
                    367:                 * boot device.
                    368:                 */
                    369:                for (dv = alldevs.tqh_first; dv != NULL;
                    370:                dv = dv->dv_list.tqe_next) {
1.28      drochner  371:                        if (dv->dv_class != DV_DISK)
1.25      drochner  372:                                continue;
                    373:
1.26      thorpej   374:                        if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "fd")) {
                    375:                                /*
                    376:                                 * Assume the configured unit number matches
                    377:                                 * the BIOS device number.  (This is the old
                    378:                                 * behaviour.)  Needs some ideas how to handle
                    379:                                 * BIOS's "swap floppy drive" options.
                    380:                                 */
                    381:                                if ((bid->biosdev & 0x80) ||
                    382:                                    dv->dv_unit != bid->biosdev)
1.25      drochner  383:                                        continue;
                    384:
                    385:                                goto found;
                    386:                        }
                    387:
1.28      drochner  388:                        if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
                    389:                            !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd")) {
1.26      thorpej   390:                                /*
1.28      drochner  391:                                 * Don't trust BIOS device numbers, try
                    392:                                 * to match the information passed by the
                    393:                                 * bootloader instead.
1.26      thorpej   394:                                 */
1.28      drochner  395:                                if ((bid->biosdev & 0x80) == 0 ||
                    396:                                    !match_harddisk(dv, bid))
1.25      drochner  397:                                        continue;
                    398:
1.28      drochner  399:                                goto found;
1.25      drochner  400:                        }
                    401:
                    402:                        /* no "fd", "wd" or "sd" */
                    403:                        continue;
                    404:
                    405: found:
1.26      thorpej   406:                        if (*devpp) {
                    407:                                printf("warning: double match for boot "
                    408:                                    "device (%s, %s)\n", (*devpp)->dv_xname,
                    409:                                    dv->dv_xname);
1.25      drochner  410:                                continue;
                    411:                        }
                    412:                        *devpp = dv;
                    413:                        *partp = bid->partition;
                    414:                }
                    415:
1.26      thorpej   416:                if (*devpp)
1.25      drochner  417:                        return;
                    418:        }
                    419:
1.43      drochner  420: #ifdef COMPAT_OLDBOOT
1.20      christos  421: #if 0
1.22      christos  422:        printf("howto %x bootdev %x ", boothowto, bootdev);
1.20      christos  423: #endif
1.23      thorpej   424:
                    425:        if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
1.1       cgd       426:                return;
1.23      thorpej   427:
1.1       cgd       428:        majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
1.38      thorpej   429:        for (i = 0; dev_name2blk[i].d_name != NULL; i++)
                    430:                if (majdev == dev_name2blk[i].d_maj)
1.23      thorpej   431:                        break;
1.38      thorpej   432:        if (dev_name2blk[i].d_name == NULL)
1.1       cgd       433:                return;
1.23      thorpej   434:
1.1       cgd       435:        part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
                    436:        unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
1.23      thorpej   437:
1.38      thorpej   438:        sprintf(buf, "%s%d", dev_name2blk[i].d_name, unit);
1.23      thorpej   439:        for (dv = alldevs.tqh_first; dv != NULL;
                    440:            dv = dv->dv_list.tqe_next) {
                    441:                if (strcmp(buf, dv->dv_xname) == 0) {
                    442:                        *devpp = dv;
                    443:                        *partp = part;
                    444:                        return;
1.1       cgd       445:                }
                    446:        }
1.43      drochner  447: #endif
1.25      drochner  448: }
                    449:
1.26      thorpej   450: #include "pci.h"
                    451:
1.25      drochner  452: #include <dev/isa/isavar.h>
1.26      thorpej   453: #if NPCI > 0
1.25      drochner  454: #include <dev/pci/pcivar.h>
1.26      thorpej   455: #endif
1.25      drochner  456:
                    457: void
                    458: device_register(dev, aux)
                    459:        struct device *dev;
                    460:        void *aux;
                    461: {
                    462:        /*
                    463:         * Handle network interfaces here, the attachment information is
                    464:         * not available driver independantly later.
                    465:         * For disks, there is nothing useful available at attach time.
                    466:         */
1.26      thorpej   467:        if (dev->dv_class == DV_IFNET) {
1.25      drochner  468:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
1.26      thorpej   469:                if (bin == NULL)
1.25      drochner  470:                        return;
                    471:
1.44    ! drochner  472:                /*
        !           473:                 * We don't check the driver name against the device name
        !           474:                 * passed by the boot ROM. The ROM should stay usable
        !           475:                 * if the driver gets obsoleted.
        !           476:                 * The physical attachment information (checked below)
        !           477:                 * must be sufficient to identify the device.
        !           478:                 */
1.25      drochner  479:
1.26      thorpej   480:                if (bin->bus == BI_BUS_ISA &&
                    481:                    !strcmp(dev->dv_parent->dv_cfdata->cf_driver->cd_name,
                    482:                    "isa")) {
1.25      drochner  483:                        struct isa_attach_args *iaa = aux;
                    484:
                    485:                        /* compare IO base address */
1.26      thorpej   486:                        if (bin->addr.iobase == iaa->ia_iobase)
1.27      drochner  487:                                goto found;
1.25      drochner  488:                }
1.26      thorpej   489: #if NPCI > 0
                    490:                if (bin->bus == BI_BUS_PCI &&
                    491:                    !strcmp(dev->dv_parent->dv_cfdata->cf_driver->cd_name,
                    492:                    "pci")) {
1.25      drochner  493:                        struct pci_attach_args *paa = aux;
                    494:                        int b, d, f;
                    495:
1.26      thorpej   496:                        /*
                    497:                         * Calculate BIOS representation of:
                    498:                         *
                    499:                         *      <bus,device,function>
                    500:                         *
                    501:                         * and compare.
                    502:                         */
1.25      drochner  503:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
1.26      thorpej   504:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
1.25      drochner  505:                                goto found;
                    506:                }
1.26      thorpej   507: #endif
1.25      drochner  508:        }
                    509:        return;
                    510:
                    511: found:
1.26      thorpej   512:        if (booted_device) {
1.25      drochner  513:                /* XXX should be a "panic()" */
                    514:                printf("warning: double match for boot device (%s, %s)\n",
1.26      thorpej   515:                    booted_device->dv_xname, dev->dv_xname);
1.25      drochner  516:                return;
                    517:        }
                    518:        booted_device = dev;
1.1       cgd       519: }

CVSweb <webmaster@jp.NetBSD.org>