[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.47

1.47    ! ad          1: /*     $NetBSD: autoconf.c,v 1.46 2000/03/21 19:38:24 ad 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.45      thorpej    78: #include "bios32.h"
                     79: #if NBIOS32 > 0
                     80: #include <machine/bios32.h>
                     81: #endif
                     82:
                     83: #include "opt_pcibios.h"
                     84: #ifdef PCIBIOS
                     85: #include <dev/pci/pcireg.h>
                     86: #include <dev/pci/pcivar.h>
                     87: #include <i386/pci/pcibios.h>
                     88: #endif
                     89:
1.1       cgd        90: /*
                     91:  * Determine i/o configuration for a machine.
                     92:  */
1.19      mycroft    93: void
1.40      thorpej    94: cpu_configure()
1.1       cgd        95: {
                     96:
1.12      mycroft    97:        startrtclock();
1.45      thorpej    98:
                     99: #if NBIOS32 > 0
                    100:        bios32_init();
                    101: #endif
                    102: #ifdef PCIBIOS
                    103:        pcibios_init();
                    104: #endif
1.12      mycroft   105:
1.18      cgd       106:        if (config_rootfound("mainbus", NULL) == NULL)
                    107:                panic("configure: mainbus not configured");
1.12      mycroft   108:
1.22      christos  109:        printf("biomask %x netmask %x ttymask %x\n",
1.12      mycroft   110:            (u_short)imask[IPL_BIO], (u_short)imask[IPL_NET],
                    111:            (u_short)imask[IPL_TTY]);
                    112:
                    113:        spl0();
1.37      thorpej   114:
                    115:        /* Set up proc0's TSS and LDT (after the FPU is configured). */
                    116:        i386_proc0_tss_ldt_init();
1.30      thorpej   117:
                    118:        /* XXX Finish deferred buffer cache allocation. */
                    119:        i386_bufinit();
1.24      gwr       120: }
1.28      drochner  121:
1.24      gwr       122: void
                    123: cpu_rootconf()
                    124: {
                    125:        struct device *booted_device;
                    126:        int booted_partition;
1.1       cgd       127:
1.23      thorpej   128:        findroot(&booted_device, &booted_partition);
1.32      fvdl      129:        matchbiosdisks();
1.23      thorpej   130:
                    131:        printf("boot device: %s\n",
                    132:            booted_device ? booted_device->dv_xname : "<unknown>");
                    133:
1.38      thorpej   134:        setroot(booted_device, booted_partition);
1.1       cgd       135: }
                    136:
1.34      fvdl      137: /*
                    138:  * XXX ugly bit of code. But, this is the only safe time that the
                    139:  * match between BIOS disks and native disks can be done.
                    140:  */
1.32      fvdl      141: static void
                    142: matchbiosdisks()
                    143: {
                    144:        struct btinfo_biosgeom *big;
                    145:        struct bi_biosgeom_entry *be;
                    146:        struct device *dv;
                    147:        struct devnametobdevmaj *d;
1.34      fvdl      148:        int i, ck, error, m, n;
1.32      fvdl      149:        struct vnode *tv;
1.34      fvdl      150:        char mbr[DEV_BSIZE];
1.32      fvdl      151:
                    152:        big = lookup_bootinfo(BTINFO_BIOSGEOM);
                    153:
1.36      fvdl      154:        if (big == NULL)
1.32      fvdl      155:                return;
                    156:
1.34      fvdl      157:        /*
                    158:         * First, count all native disks
                    159:         */
                    160:        for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next)
                    161:                if (dv->dv_class == DV_DISK &&
                    162:                    (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
1.47    ! ad        163:                     !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd") ||
        !           164:                     !strcmp(dv->dv_cfdata->cf_driver->cd_name, "ca")))
1.35      fvdl      165:                        i386_ndisks++;
                    166:
                    167:        if (i386_ndisks == 0)
                    168:                return;
1.34      fvdl      169:
                    170:        /* XXX M_TEMP is wrong */
1.35      fvdl      171:        i386_alldisks = malloc(sizeof (struct disklist) + (i386_ndisks - 1) *
                    172:                                sizeof (struct nativedisk_info),
                    173:                                M_TEMP, M_NOWAIT);
                    174:        if (i386_alldisks == NULL)
1.34      fvdl      175:                return;
                    176:
1.35      fvdl      177:        i386_alldisks->dl_nnativedisks = i386_ndisks;
                    178:        i386_alldisks->dl_nbiosdisks = big->num;
                    179:        for (i = 0; i < big->num; i++) {
                    180:                i386_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
                    181:                i386_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
                    182:                i386_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
                    183:                i386_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
                    184:                i386_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
                    185:                i386_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
                    186:        }
                    187:
1.34      fvdl      188:        /*
                    189:         * XXX code duplication from findroot()
                    190:         */
                    191:        n = -1;
1.32      fvdl      192:        for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
                    193:                if (dv->dv_class != DV_DISK)
                    194:                        continue;
                    195: #ifdef GEOM_DEBUG
                    196:                printf("matchbiosdisks: trying to match (%s) %s\n",
                    197:                    dv->dv_xname, dv->dv_cfdata->cf_driver->cd_name);
                    198: #endif
                    199:                if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
1.47    ! ad        200:                    !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd") ||
        !           201:                    !strcmp(dv->dv_cfdata->cf_driver->cd_name, "ca")) {
1.34      fvdl      202:                        n++;
1.35      fvdl      203:                        sprintf(i386_alldisks->dl_nativedisks[n].ni_devname,
                    204:                            "%s%d", dv->dv_cfdata->cf_driver->cd_name,
1.34      fvdl      205:                            dv->dv_unit);
                    206:
1.38      thorpej   207:                        for (d = dev_name2blk; d->d_name &&
1.32      fvdl      208:                           strcmp(d->d_name, dv->dv_cfdata->cf_driver->cd_name);
                    209:                           d++);
                    210:                        if (d->d_name == NULL)
                    211:                                return;
1.34      fvdl      212:
1.32      fvdl      213:                        if (bdevvp(MAKEDISKDEV(d->d_maj, dv->dv_unit, RAW_PART),
                    214:                            &tv))
                    215:                                panic("matchbiosdisks: can't alloc vnode");
1.34      fvdl      216:
1.33      fvdl      217:                        error = VOP_OPEN(tv, FREAD, NOCRED, 0);
                    218:                        if (error) {
1.42      fvdl      219:                                vput(tv);
1.33      fvdl      220:                                continue;
                    221:                        }
1.34      fvdl      222:                        error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
                    223:                            UIO_SYSSPACE, 0, NOCRED, NULL, 0);
                    224:                        VOP_CLOSE(tv, FREAD, NOCRED, 0);
                    225:                        if (error) {
1.32      fvdl      226: #ifdef GEOM_DEBUG
                    227:                                printf("matchbiosdisks: %s: MBR read failure\n",
                    228:                                    dv->dv_xname);
                    229: #endif
                    230:                                continue;
                    231:                        }
1.34      fvdl      232:
1.32      fvdl      233:                        for (ck = i = 0; i < DEV_BSIZE; i++)
                    234:                                ck += mbr[i];
1.34      fvdl      235:                        for (m = i = 0; i < big->num; i++) {
1.32      fvdl      236:                                be = &big->disk[i];
                    237: #ifdef GEOM_DEBUG
                    238:                                printf("match %s with %d\n", dv->dv_xname, i);
                    239:                                printf("dev ck %x bios ck %x\n", ck, be->cksum);
                    240: #endif
                    241:                                if (be->flags & BI_GEOM_INVALID)
                    242:                                        continue;
                    243:                                if (be->cksum == ck &&
                    244:                                    !memcmp(&mbr[MBR_PARTOFF], be->dosparts,
                    245:                                        NMBRPART *
                    246:                                            sizeof (struct mbr_partition))) {
                    247: #ifdef GEOM_DEBUG
                    248:                                        printf("matched bios disk %x with %s\n",
                    249:                                            be->dev, be->devname);
                    250: #endif
1.35      fvdl      251:                                        i386_alldisks->dl_nativedisks[n].
                    252:                                            ni_biosmatches[m++] = i;
1.32      fvdl      253:                                }
                    254:                        }
1.35      fvdl      255:                        i386_alldisks->dl_nativedisks[n].ni_nmatches = m;
1.42      fvdl      256:                        vput(tv);
1.32      fvdl      257:                }
                    258:        }
                    259: }
                    260:
1.43      drochner  261: #ifdef COMPAT_OLDBOOT
1.1       cgd       262: u_long bootdev = 0;            /* should be dev_t, but not until 32 bits */
1.43      drochner  263: #endif
1.25      drochner  264: struct device *booted_device;
1.1       cgd       265:
                    266: /*
1.28      drochner  267:  * helper function for "findroot()":
                    268:  * return nonzero if disk device matches bootinfo
                    269:  */
1.32      fvdl      270: static int
                    271: match_harddisk(dv, bid)
1.28      drochner  272:        struct device *dv;
                    273:        struct btinfo_bootdisk *bid;
                    274: {
                    275:        struct devnametobdevmaj *i;
                    276:        struct vnode *tmpvn;
                    277:        int error;
                    278:        struct disklabel label;
                    279:        int found = 0;
                    280:
                    281:        /*
                    282:         * A disklabel is required here.  The
                    283:         * bootblocks don't refuse to boot from
                    284:         * a disk without a label, but this is
                    285:         * normally not wanted.
                    286:         */
                    287:        if (bid->labelsector == -1)
                    288:                return(0);
                    289:
                    290:        /*
                    291:         * lookup major number for disk block device
                    292:         */
1.38      thorpej   293:        i = dev_name2blk;
1.28      drochner  294:        while (i->d_name &&
                    295:               strcmp(i->d_name, dv->dv_cfdata->cf_driver->cd_name))
                    296:                i++;
                    297:        if (i->d_name == NULL)
                    298:                return(0); /* XXX panic() ??? */
                    299:
                    300:        /*
                    301:         * Fake a temporary vnode for the disk, open
                    302:         * it, and read the disklabel for comparison.
                    303:         */
                    304:        if (bdevvp(MAKEDISKDEV(i->d_maj, dv->dv_unit, bid->partition), &tmpvn))
                    305:                panic("findroot can't alloc vnode");
                    306:        error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
                    307:        if (error) {
                    308: #ifndef DEBUG
1.31      bouyer    309:                /*
                    310:                 * Ignore errors caused by missing
                    311:                 * device, partition or medium.
                    312:                 */
                    313:                if (error != ENXIO && error != ENODEV)
1.28      drochner  314: #endif
                    315:                        printf("findroot: can't open dev %s%c (%d)\n",
                    316:                               dv->dv_xname, 'a' + bid->partition, error);
1.42      fvdl      317:                vput(tmpvn);
1.28      drochner  318:                return(0);
                    319:        }
                    320:        error = VOP_IOCTL(tmpvn, DIOCGDINFO, (caddr_t)&label, FREAD, NOCRED, 0);
                    321:        if (error) {
                    322:                /*
                    323:                 * XXX can't happen - open() would
                    324:                 * have errored out (or faked up one)
                    325:                 */
                    326:                printf("can't get label for dev %s%c (%d)\n",
                    327:                       dv->dv_xname, 'a' + bid->partition, error);
                    328:                goto closeout;
                    329:        }
                    330:
                    331:        /* compare with our data */
                    332:        if (label.d_type == bid->label.type &&
                    333:            label.d_checksum == bid->label.checksum &&
                    334:            !strncmp(label.d_packname, bid->label.packname, 16))
                    335:                found = 1;
                    336:
                    337: closeout:
                    338:        VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
1.42      fvdl      339:        vput(tmpvn);
1.28      drochner  340:        return(found);
                    341: }
                    342:
                    343: /*
1.1       cgd       344:  * Attempt to find the device from which we were booted.
                    345:  * If we can do so, and not instructed not to do so,
                    346:  * change rootdev to correspond to the load device.
                    347:  */
1.19      mycroft   348: void
1.23      thorpej   349: findroot(devpp, partp)
                    350:        struct device **devpp;
                    351:        int *partp;
1.1       cgd       352: {
1.25      drochner  353:        struct btinfo_bootdisk *bid;
                    354:        struct device *dv;
1.43      drochner  355: #ifdef COMPAT_OLDBOOT
1.23      thorpej   356:        int i, majdev, unit, part;
                    357:        char buf[32];
1.43      drochner  358: #endif
1.23      thorpej   359:
                    360:        /*
                    361:         * Default to "not found."
                    362:         */
                    363:        *devpp = NULL;
                    364:        *partp = 0;
1.1       cgd       365:
1.26      thorpej   366:        if (booted_device) {
1.25      drochner  367:                *devpp = booted_device;
                    368:                return;
                    369:        }
1.26      thorpej   370:        if (lookup_bootinfo(BTINFO_NETIF)) {
1.25      drochner  371:                /*
                    372:                 * We got netboot interface information, but
                    373:                 * "device_register()" couldn't match it to a configured
                    374:                 * device. Bootdisk information cannot be present at the
                    375:                 * same time, so give up.
                    376:                 */
                    377:                printf("findroot: netboot interface not found\n");
                    378:                return;
                    379:        }
                    380:
                    381:        bid = lookup_bootinfo(BTINFO_BOOTDISK);
1.26      thorpej   382:        if (bid) {
1.25      drochner  383:                /*
                    384:                 * Scan all disk devices for ones that match the passed data.
                    385:                 * Don't break if one is found, to get possible multiple
                    386:                 * matches - for problem tracking. Use the first match anyway
                    387:                 * because lower device numbers are more likely to be the
                    388:                 * boot device.
                    389:                 */
                    390:                for (dv = alldevs.tqh_first; dv != NULL;
                    391:                dv = dv->dv_list.tqe_next) {
1.28      drochner  392:                        if (dv->dv_class != DV_DISK)
1.25      drochner  393:                                continue;
                    394:
1.26      thorpej   395:                        if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "fd")) {
                    396:                                /*
                    397:                                 * Assume the configured unit number matches
                    398:                                 * the BIOS device number.  (This is the old
                    399:                                 * behaviour.)  Needs some ideas how to handle
                    400:                                 * BIOS's "swap floppy drive" options.
                    401:                                 */
                    402:                                if ((bid->biosdev & 0x80) ||
                    403:                                    dv->dv_unit != bid->biosdev)
1.25      drochner  404:                                        continue;
                    405:
                    406:                                goto found;
                    407:                        }
                    408:
1.28      drochner  409:                        if (!strcmp(dv->dv_cfdata->cf_driver->cd_name, "sd") ||
1.46      ad        410:                            !strcmp(dv->dv_cfdata->cf_driver->cd_name, "wd") ||
                    411:                            !strcmp(dv->dv_cfdata->cf_driver->cd_name, "ca")) {
1.26      thorpej   412:                                /*
1.28      drochner  413:                                 * Don't trust BIOS device numbers, try
                    414:                                 * to match the information passed by the
                    415:                                 * bootloader instead.
1.26      thorpej   416:                                 */
1.28      drochner  417:                                if ((bid->biosdev & 0x80) == 0 ||
                    418:                                    !match_harddisk(dv, bid))
1.25      drochner  419:                                        continue;
                    420:
1.28      drochner  421:                                goto found;
1.25      drochner  422:                        }
                    423:
1.46      ad        424:                        /* no "fd", "wd", "sd" or "ca" */
1.25      drochner  425:                        continue;
                    426:
                    427: found:
1.26      thorpej   428:                        if (*devpp) {
                    429:                                printf("warning: double match for boot "
                    430:                                    "device (%s, %s)\n", (*devpp)->dv_xname,
                    431:                                    dv->dv_xname);
1.25      drochner  432:                                continue;
                    433:                        }
                    434:                        *devpp = dv;
                    435:                        *partp = bid->partition;
                    436:                }
                    437:
1.26      thorpej   438:                if (*devpp)
1.25      drochner  439:                        return;
                    440:        }
                    441:
1.43      drochner  442: #ifdef COMPAT_OLDBOOT
1.20      christos  443: #if 0
1.22      christos  444:        printf("howto %x bootdev %x ", boothowto, bootdev);
1.20      christos  445: #endif
1.23      thorpej   446:
                    447:        if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
1.1       cgd       448:                return;
1.23      thorpej   449:
1.1       cgd       450:        majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
1.38      thorpej   451:        for (i = 0; dev_name2blk[i].d_name != NULL; i++)
                    452:                if (majdev == dev_name2blk[i].d_maj)
1.23      thorpej   453:                        break;
1.38      thorpej   454:        if (dev_name2blk[i].d_name == NULL)
1.1       cgd       455:                return;
1.23      thorpej   456:
1.1       cgd       457:        part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
                    458:        unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
1.23      thorpej   459:
1.38      thorpej   460:        sprintf(buf, "%s%d", dev_name2blk[i].d_name, unit);
1.23      thorpej   461:        for (dv = alldevs.tqh_first; dv != NULL;
                    462:            dv = dv->dv_list.tqe_next) {
                    463:                if (strcmp(buf, dv->dv_xname) == 0) {
                    464:                        *devpp = dv;
                    465:                        *partp = part;
                    466:                        return;
1.1       cgd       467:                }
                    468:        }
1.43      drochner  469: #endif
1.25      drochner  470: }
                    471:
1.26      thorpej   472: #include "pci.h"
                    473:
1.25      drochner  474: #include <dev/isa/isavar.h>
1.26      thorpej   475: #if NPCI > 0
1.25      drochner  476: #include <dev/pci/pcivar.h>
1.26      thorpej   477: #endif
1.25      drochner  478:
                    479: void
                    480: device_register(dev, aux)
                    481:        struct device *dev;
                    482:        void *aux;
                    483: {
                    484:        /*
                    485:         * Handle network interfaces here, the attachment information is
                    486:         * not available driver independantly later.
                    487:         * For disks, there is nothing useful available at attach time.
                    488:         */
1.26      thorpej   489:        if (dev->dv_class == DV_IFNET) {
1.25      drochner  490:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
1.26      thorpej   491:                if (bin == NULL)
1.25      drochner  492:                        return;
                    493:
1.44      drochner  494:                /*
                    495:                 * We don't check the driver name against the device name
                    496:                 * passed by the boot ROM. The ROM should stay usable
                    497:                 * if the driver gets obsoleted.
                    498:                 * The physical attachment information (checked below)
                    499:                 * must be sufficient to identify the device.
                    500:                 */
1.25      drochner  501:
1.26      thorpej   502:                if (bin->bus == BI_BUS_ISA &&
                    503:                    !strcmp(dev->dv_parent->dv_cfdata->cf_driver->cd_name,
                    504:                    "isa")) {
1.25      drochner  505:                        struct isa_attach_args *iaa = aux;
                    506:
                    507:                        /* compare IO base address */
1.26      thorpej   508:                        if (bin->addr.iobase == iaa->ia_iobase)
1.27      drochner  509:                                goto found;
1.25      drochner  510:                }
1.26      thorpej   511: #if NPCI > 0
                    512:                if (bin->bus == BI_BUS_PCI &&
                    513:                    !strcmp(dev->dv_parent->dv_cfdata->cf_driver->cd_name,
                    514:                    "pci")) {
1.25      drochner  515:                        struct pci_attach_args *paa = aux;
                    516:                        int b, d, f;
                    517:
1.26      thorpej   518:                        /*
                    519:                         * Calculate BIOS representation of:
                    520:                         *
                    521:                         *      <bus,device,function>
                    522:                         *
                    523:                         * and compare.
                    524:                         */
1.25      drochner  525:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
1.26      thorpej   526:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
1.25      drochner  527:                                goto found;
                    528:                }
1.26      thorpej   529: #endif
1.25      drochner  530:        }
                    531:        return;
                    532:
                    533: found:
1.26      thorpej   534:        if (booted_device) {
1.25      drochner  535:                /* XXX should be a "panic()" */
                    536:                printf("warning: double match for boot device (%s, %s)\n",
1.26      thorpej   537:                    booted_device->dv_xname, dev->dv_xname);
1.25      drochner  538:                return;
                    539:        }
                    540:        booted_device = dev;
1.1       cgd       541: }

CVSweb <webmaster@jp.NetBSD.org>