summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoritojun <itojun@NetBSD.org>2003-08-15 07:17:21 +0000
committeritojun <itojun@NetBSD.org>2003-08-15 07:17:21 +0000
commitc2ab035d779cbbd0cd042409c006032dd5376a92 (patch)
tree1f1840eef290358dea09f3b13afc9056963f479e /sys/dev
parent35b86d9c94baed930f18b62a8223ff60a5e8e73c (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.c32
-rw-r--r--sys/dev/pci/pci_quirks.c6
-rw-r--r--sys/dev/pci/pcivar.h12
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;