Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Clean up the AGP match/attach code somewhat.
details: https://anonhg.NetBSD.org/src/rev/3b504412070d
branches: trunk
changeset: 514959:3b504412070d
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Sep 15 00:24:59 2001 +0000
description:
Clean up the AGP match/attach code somewhat.
diffstat:
sys/arch/i386/pci/pchb.c | 89 +++++++++++++++++++++++-------
sys/dev/pci/agp.c | 132 ++++++++++++++++++++++++++++++++--------------
sys/dev/pci/agp_ali.c | 14 +----
sys/dev/pci/agp_amd.c | 9 +--
sys/dev/pci/agp_i810.c | 55 ++-----------------
sys/dev/pci/agp_intel.c | 15 +----
sys/dev/pci/agp_sis.c | 15 +----
sys/dev/pci/agp_via.c | 14 +----
sys/dev/pci/agpvar.h | 14 +---
9 files changed, 174 insertions(+), 183 deletions(-)
diffs (truncated from 575 to 300 lines):
diff -r 02c52b18c9d8 -r 3b504412070d sys/arch/i386/pci/pchb.c
--- a/sys/arch/i386/pci/pchb.c Fri Sep 14 21:44:21 2001 +0000
+++ b/sys/arch/i386/pci/pchb.c Sat Sep 15 00:24:59 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pchb.c,v 1.26 2001/09/12 08:25:17 fvdl Exp $ */
+/* $NetBSD: pchb.c,v 1.27 2001/09/15 00:25:01 thorpej Exp $ */
/*-
* Copyright (c) 1996, 1998, 2000 The NetBSD Foundation, Inc.
@@ -48,12 +48,12 @@
#include <dev/pci/pcidevs.h>
+#include <dev/pci/agpreg.h>
#include <dev/pci/agpvar.h>
#include <arch/i386/pci/pchbvar.h>
#include "rnd.h"
-#include "agp.h"
#define PCISET_BRIDGETYPE_MASK 0x3
#define PCISET_TYPE_COMPAT 0x1
@@ -78,6 +78,8 @@
int pchbmatch __P((struct device *, struct cfdata *, void *));
void pchbattach __P((struct device *, struct device *, void *));
+int pchb_i810_vgamatch(struct pci_attach_args *);
+
int pchb_print __P((void *, const char *));
int agp_print __P((void *, const char *));
@@ -107,16 +109,15 @@
struct pci_attach_args *pa = aux;
char devinfo[256];
struct pcibus_attach_args pba;
-#if NAGP > 0
- struct agp_phcb_attach_args apa;
-#endif
+ struct agpbus_attach_args apa;
pcireg_t bcreg;
u_char bdnum, pbnum;
pcitag_t tag;
- int doattach, attachflags;
+ int doattach, attachflags, has_agp;
printf("\n");
doattach = 0;
+ has_agp = 0;
attachflags = pa->pa_flags;
/*
@@ -251,6 +252,48 @@
break;
}
break;
+
+ case PCI_PRODUCT_INTEL_82810_MCH:
+ case PCI_PRODUCT_INTEL_82810_DC100_MCH:
+ case PCI_PRODUCT_INTEL_82810E_MCH:
+ case PCI_PRODUCT_INTEL_82815_FULL_HUB:
+ {
+ struct pci_attach_args vga_pa;
+ pcireg_t ramreg;
+
+ /*
+ * XXXfvdl
+ * This relies on the "memory hub" and the VGA controller
+ * being on the same bus, which is kind of gross. Fortunately,
+ * we know this is always the case on the i810.
+ */
+ if (pci_find_device(&vga_pa, pchb_i810_vgamatch) != 0) {
+ ramreg = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ AGP_I810_SMRAM);
+ if (ramreg & 0xff)
+ has_agp = 1;
+ }
+ break;
+ }
+ }
+
+#if NRND > 0
+ /*
+ * Attach a random number generator, if there is one.
+ */
+ pchb_attach_rnd(sc, pa);
+#endif
+
+ /*
+ * If we haven't detected AGP yet (via a product ID),
+ * then check for AGP capability on the device.
+ */
+ if (has_agp ||
+ pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
+ NULL, NULL) != 0) {
+ apa.apa_busname = "agp";
+ apa.apa_pci_args = *pa;
+ config_found(self, &apa, agp_print);
}
if (doattach) {
@@ -263,23 +306,25 @@
pba.pba_pc = pa->pa_pc;
config_found(self, &pba, pchb_print);
}
+}
-#if NAGP > 0
- /*
- * XXX re-use of pci attach args for pchb, but it's probably
- * the best thing to do.
- */
- apa.apa_busname = "agp";
- apa.apa_pci_args = *pa;
- config_found(self, &apa, agp_print);
-#endif
+int
+pchb_i810_vgamatch(struct pci_attach_args *pa)
+{
+
+ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
+ PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
+ return (0);
-#if NRND > 0
- /*
- * Attach a random number generator, if there is one.
- */
- pchb_attach_rnd(sc, pa);
-#endif
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82810_GC:
+ case PCI_PRODUCT_INTEL_82810_DC100_GC:
+ case PCI_PRODUCT_INTEL_82810E_GC:
+ case PCI_PRODUCT_INTEL_82815_FULL_GRAPH:
+ return (1);
+ }
+
+ return (0);
}
int
@@ -296,7 +341,7 @@
int
agp_print(void *aux, const char *pnp)
{
- struct agp_phcb_attach_args *apa = aux;
+ struct agpbus_attach_args *apa = aux;
if (pnp)
printf("%s at %s", apa->apa_busname, pnp);
return (UNCONF);
diff -r 02c52b18c9d8 -r 3b504412070d sys/dev/pci/agp.c
--- a/sys/dev/pci/agp.c Fri Sep 14 21:44:21 2001 +0000
+++ b/sys/dev/pci/agp.c Sat Sep 15 00:24:59 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: agp.c,v 1.4 2001/09/14 12:09:14 drochner Exp $ */
+/* $NetBSD: agp.c,v 1.5 2001/09/15 00:24:59 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@@ -106,30 +106,93 @@
static int agp_unbind_user(struct agp_softc *, agp_unbind *);
static int agpdev_match(struct pci_attach_args *);
+const struct agp_product {
+ uint32_t ap_vendor;
+ uint32_t ap_product;
+ int (*ap_match)(const struct pci_attach_args *);
+ int (*ap_attach)(struct device *, struct device *, void *);
+} agp_products[] = {
+ { PCI_VENDOR_ALI, -1,
+ NULL, agp_ali_attach },
+
+ { PCI_VENDOR_AMD, -1,
+ agp_amd_match, agp_amd_attach },
+
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_MCH,
+ NULL, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_DC100_MCH,
+ NULL, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810E_MCH,
+ NULL, agp_i810_attach },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82815_FULL_HUB,
+ NULL, agp_i810_attach },
+
+ { PCI_VENDOR_INTEL, -1,
+ NULL, agp_intel_attach },
+
+ { PCI_VENDOR_SIS, -1,
+ NULL, agp_sis_attach },
+
+ { PCI_VENDOR_VIATECH, -1,
+ NULL, agp_via_attach },
+
+ { 0, 0,
+ NULL, NULL },
+};
+
+static const struct agp_product *
+agp_lookup(const struct pci_attach_args *pa)
+{
+ const struct agp_product *ap;
+
+ /* First find the vendor. */
+ for (ap = agp_products; ap->ap_attach != NULL; ap++) {
+ if (PCI_VENDOR(pa->pa_id) == ap->ap_vendor)
+ break;
+ }
+
+ if (ap->ap_attach == NULL)
+ return (NULL);
+
+ /* Now find the product within the vendor's domain. */
+ for (; ap->ap_attach != NULL; ap++) {
+ if (PCI_VENDOR(pa->pa_id) != ap->ap_vendor) {
+ /* Ran out of this vendor's section of the table. */
+ return (NULL);
+ }
+ if (ap->ap_product == PCI_PRODUCT(pa->pa_id)) {
+ /* Exact match. */
+ break;
+ }
+ if (ap->ap_product == (uint32_t) -1) {
+ /* Wildcard match. */
+ break;
+ }
+ }
+
+ if (ap->ap_attach == NULL)
+ return (NULL);
+
+ /* Now let the product-specific driver filter the match. */
+ if (ap->ap_match != NULL && (*ap->ap_match)(pa) == 0)
+ return (NULL);
+
+ return (ap);
+}
+
int
agpmatch(struct device *parent, struct cfdata *match, void *aux)
{
- struct agp_phcb_attach_args *apa = aux;
+ struct agpbus_attach_args *apa = aux;
struct pci_attach_args *pa = &apa->apa_pci_args;
- switch (PCI_VENDOR(pa->pa_id)) {
- case PCI_VENDOR_ALI:
- return agp_ali_match(parent, match, pa);
- case PCI_VENDOR_AMD:
- return agp_amd_match(parent, match, pa);
- case PCI_VENDOR_INTEL:
- if (agp_i810_bridgematch(pa))
- return agp_i810_match(parent, match, pa);
- return agp_intel_match(parent, match, pa);
- case PCI_VENDOR_SIS:
- return agp_sis_match(parent, match, pa);
- case PCI_VENDOR_VIATECH:
- return agp_via_match(parent, match, pa);
- default:
- return 0;
- }
+ if (strcmp(apa->apa_busname, "agp") != 0)
+ return (0);
- return (0);
+ if (agp_lookup(pa) == NULL)
+ return (0);
+
+ return (1);
}
static int agp_max[][2] = {
@@ -148,11 +211,17 @@
void
agpattach(struct device *parent, struct device *self, void *aux)
{
- struct agp_phcb_attach_args *apa = aux;
+ struct agpbus_attach_args *apa = aux;
struct pci_attach_args *pa = &apa->apa_pci_args;
struct agp_softc *sc = (void *)self;
+ const struct agp_product *ap;
int memsize, i, ret;
+ ap = agp_lookup(pa);
+ if (ap == NULL) {
+ printf("\n");
+ panic("agpattach: impossible");
+ }
sc->as_dmat = pa->pa_dmat;
sc->as_pc = pa->pa_pc;
@@ -180,28 +249,7 @@
TAILQ_INIT(&sc->as_memory);
- switch (PCI_VENDOR(pa->pa_id)) {
- case PCI_VENDOR_ALI:
- ret = agp_ali_attach(parent, self, pa);
- break;
- case PCI_VENDOR_AMD:
Home |
Main Index |
Thread Index |
Old Index