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