diff options
| author | itojun <itojun@NetBSD.org> | 2003-08-15 07:17:21 +0000 |
|---|---|---|
| committer | itojun <itojun@NetBSD.org> | 2003-08-15 07:17:21 +0000 |
| commit | c2ab035d779cbbd0cd042409c006032dd5376a92 (patch) | |
| tree | 1f1840eef290358dea09f3b13afc9056963f479e /sys/dev | |
| parent | 35b86d9c94baed930f18b62a8223ff60a5e8e73c (diff) | |
- check HDRTYPE early, and ignore if it is not supported (n > 2).
- defer access to interrupt configuration register, as its existence depends on
HDRTYPE.
- add "skip particular funtion in multifunction device" functionality
to quirk table.
- add GEODE/NS SC1100 quirk (now boots on soekris Net4801).
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/pci.c | 32 | ||||
| -rw-r--r-- | sys/dev/pci/pci_quirks.c | 6 | ||||
| -rw-r--r-- | sys/dev/pci/pcivar.h | 12 |
3 files changed, 38 insertions, 12 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 95f55375ee7..613770f1b30 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: pci.c,v 1.80 2003/06/15 23:09:09 fvdl Exp $ */ +/* $NetBSD: pci.c,v 1.81 2003/08/15 07:17:21 itojun Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.80 2003/06/15 23:09:09 fvdl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.81 2003/08/15 07:17:21 itojun Exp $"); #include "opt_pci.h" @@ -262,11 +262,13 @@ pci_probe_device(struct pci_softc *sc, pcitag_t tag, pci_decompose_tag(pc, tag, &bus, &device, &function); + bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); + if (PCI_HDRTYPE_TYPE(bhlcr) > 2) + return (0); + id = pci_conf_read(pc, tag, PCI_ID_REG); csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); class = pci_conf_read(pc, tag, PCI_CLASS_REG); - intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); - bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); /* Invalid vendor ID value? */ if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) @@ -312,6 +314,9 @@ pci_probe_device(struct pci_softc *sc, pcitag_t tag, pa.pa_intrswiz = sc->sc_intrswiz + device; pa.pa_intrtag = sc->sc_intrtag; } + + intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); + pin = PCI_INTERRUPT_PIN(intr); pa.pa_rawintrpin = pin; if (pin == PCI_INTERRUPT_PIN_NONE) { @@ -431,6 +436,11 @@ pci_enumerate_bus_generic(struct pci_softc *sc, #endif { tag = pci_make_tag(pc, sc->sc_bus, device, 0); + + bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); + if (PCI_HDRTYPE_TYPE(bhlcr) > 2) + continue; + id = pci_conf_read(pc, tag, PCI_ID_REG); /* Invalid vendor ID value? */ @@ -442,15 +452,19 @@ pci_enumerate_bus_generic(struct pci_softc *sc, qd = pci_lookup_quirkdata(PCI_VENDOR(id), PCI_PRODUCT(id)); - bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); - if (PCI_HDRTYPE_MULTIFN(bhlcr) || - (qd != NULL && - (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0)) + if (qd != NULL && + (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0) nfunctions = 8; - else + else if (qd != NULL && + (qd->quirks & PCI_QUIRK_MONOFUNCTION) != 0) nfunctions = 1; + else + nfunctions = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1; for (function = 0; function < nfunctions; function++) { + if (qd != NULL && + (qd->quirks & PCI_QUIRK_SKIP_FUNC(function)) != 0) + continue; tag = pci_make_tag(pc, sc->sc_bus, device, function); ret = pci_probe_device(sc, tag, match, pap); if (match != NULL && ret != 0) diff --git a/sys/dev/pci/pci_quirks.c b/sys/dev/pci/pci_quirks.c index 4b6fe79d306..d8f3cc89725 100644 --- a/sys/dev/pci/pci_quirks.c +++ b/sys/dev/pci/pci_quirks.c @@ -1,4 +1,4 @@ -/* $NetBSD: pci_quirks.c,v 1.2 2001/11/13 07:48:47 lukem Exp $ */ +/* $NetBSD: pci_quirks.c,v 1.3 2003/08/15 07:17:21 itojun Exp $ */ /* * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_quirks.c,v 1.2 2001/11/13 07:48:47 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_quirks.c,v 1.3 2003/08/15 07:17:21 itojun Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -47,6 +47,8 @@ __KERNEL_RCSID(0, "$NetBSD: pci_quirks.c,v 1.2 2001/11/13 07:48:47 lukem Exp $") static const struct pci_quirkdata pci_quirks[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82371FB_ISA, PCI_QUIRK_MULTIFUNCTION }, + { PCI_VENDOR_NS, PCI_PRODUCT_NS_SC1100_ISA, + PCI_QUIRK_SKIP_FUNC1 | PCI_QUIRK_SKIP_FUNC4 }, }; const struct pci_quirkdata * diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 859ae55fee4..b89fca4becd 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: pcivar.h,v 1.58 2003/06/29 22:30:27 fvdl Exp $ */ +/* $NetBSD: pcivar.h,v 1.59 2003/08/15 07:17:21 itojun Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -144,6 +144,16 @@ struct pci_quirkdata { int quirks; /* quirks; see below */ }; #define PCI_QUIRK_MULTIFUNCTION 1 +#define PCI_QUIRK_MONOFUNCTION 2 +#define PCI_QUIRK_SKIP_FUNC(n) (4 << n) +#define PCI_QUIRK_SKIP_FUNC0 PCI_QUIRK_SKIP_FUNC(0) +#define PCI_QUIRK_SKIP_FUNC1 PCI_QUIRK_SKIP_FUNC(1) +#define PCI_QUIRK_SKIP_FUNC2 PCI_QUIRK_SKIP_FUNC(2) +#define PCI_QUIRK_SKIP_FUNC3 PCI_QUIRK_SKIP_FUNC(3) +#define PCI_QUIRK_SKIP_FUNC4 PCI_QUIRK_SKIP_FUNC(4) +#define PCI_QUIRK_SKIP_FUNC5 PCI_QUIRK_SKIP_FUNC(5) +#define PCI_QUIRK_SKIP_FUNC6 PCI_QUIRK_SKIP_FUNC(6) +#define PCI_QUIRK_SKIP_FUNC7 PCI_QUIRK_SKIP_FUNC(7) struct pci_softc { struct device sc_dev; |
