Clean up the AGP match/attach code somewhat.

This commit is contained in:
thorpej 2001-09-15 00:24:59 +00:00
parent 718551d644
commit 0019ea5ce6
9 changed files with 174 additions and 183 deletions

View File

@ -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 @@ pchbattach(struct device *parent, struct device *self, void *aux)
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 @@ pchbattach(struct device *parent, struct device *self, void *aux)
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 @@ pchbattach(struct device *parent, struct device *self, void *aux)
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 NRND > 0
/*
* Attach a random number generator, if there is one.
*/
pchb_attach_rnd(sc, pa);
#endif
if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
return (0);
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 @@ pchb_print(void *aux, const char *pnp)
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);

View File

@ -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_bind_user(struct agp_softc *, agp_bind *);
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);
if (agp_lookup(pa) == NULL)
return (0);
return (1);
}
static int agp_max[][2] = {
@ -148,11 +211,17 @@ static int agp_max[][2] = {
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 @@ agpattach(struct device *parent, struct device *self, void *aux)
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:
ret = agp_amd_attach(parent, self, pa);
break;
case PCI_VENDOR_INTEL:
if (agp_i810_bridgematch(pa))
ret = agp_i810_attach(parent, self, pa);
else
ret = agp_intel_attach(parent, self, pa);
break;
case PCI_VENDOR_SIS:
ret = agp_sis_attach(parent, self, pa);
break;
case PCI_VENDOR_VIATECH:
ret = agp_via_attach(parent, self, pa);
break;
default:
panic("agpattach: bad chipset detection");
}
ret = (*ap->ap_attach)(parent, self, pa);
if (ret == 0)
printf(": aperture at 0x%lx, size 0x%lx\n",
(unsigned long)sc->as_apaddr,

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_ali.c,v 1.1 2001/09/10 10:01:01 fvdl Exp $ */
/* $NetBSD: agp_ali.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -73,18 +73,6 @@ struct agp_methods agp_ali_methods = {
agp_generic_unbind_memory,
};
int
agp_ali_match(struct device *parent, struct cfdata *match, void *aux)
{
struct pci_attach_args *pa = aux;
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)
== 0)
return 0;
return 1;
}
int
agp_ali_attach(struct device *parent, struct device *self, void *aux)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_amd.c,v 1.1 2001/09/10 10:01:01 fvdl Exp $ */
/* $NetBSD: agp_amd.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -149,13 +149,8 @@ agp_amd_free_gatt(struct agp_softc *sc, struct agp_amd_gatt *gatt)
#endif
int
agp_amd_match(struct device *parent, struct cfdata *match, void *aux)
agp_amd_match(const struct pci_attach_args *pa)
{
struct pci_attach_args *pa = aux;
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)
== 0)
return 0;
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_AMD_SC751_SC:

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_i810.c,v 1.5 2001/09/14 12:05:03 drochner Exp $ */
/* $NetBSD: agp_i810.c,v 1.6 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -87,65 +87,24 @@ struct agp_methods agp_i810_methods = {
agp_i810_unbind_memory,
};
/* XXXthorpej -- duplicated code (see arch/i386/pci/pchb.c) */
static int
agp_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;
return (0);
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;
}
/*
* Find bridge device.
*/
int
agp_i810_bridgematch(struct pci_attach_args *pa)
{
switch (PCI_PRODUCT(pa->pa_id)) {
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:
return 1;
return (1);
}
return 0;
}
int
agp_i810_match(struct device *parent, struct cfdata *match, void *aux)
{
struct pci_attach_args vga_pa, *pa = aux;
pcireg_t ramreg;
if (agp_i810_bridgematch(pa) == 0)
return 0;
/*
* XXXXfvdl
* this relies on the 'memory hub' and the VGA controller
* being on the same bus, which is bad. Fortunately, we
* know this to be the case with the i810.
*
* Could just have the attach fail later, leave as_chipc NULL
* and fail any open() call.
*/
if (pci_find_device(&vga_pa, agp_i810_vgamatch) == 0)
return 0;
ramreg = pci_conf_read(pa->pa_pc, pa->pa_tag, AGP_I810_SMRAM);
if ((ramreg & 0xff) == 0)
return 0;
return 1;
return (0);
}
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_intel.c,v 1.2 2001/09/11 06:30:38 fvdl Exp $ */
/* $NetBSD: agp_intel.c,v 1.3 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -71,19 +71,6 @@ struct agp_methods agp_intel_methods = {
agp_generic_unbind_memory,
};
int
agp_intel_match(struct device *parent, struct cfdata *match, void *aux)
{
struct pci_attach_args *pa = aux;
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)
== 0)
return 0;
return 1;
}
int
agp_intel_attach(struct device *parent, struct device *self, void *aux)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_sis.c,v 1.1 2001/09/10 10:01:02 fvdl Exp $ */
/* $NetBSD: agp_sis.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -71,19 +71,6 @@ struct agp_methods agp_sis_methods = {
agp_generic_unbind_memory,
};
int
agp_sis_match(struct device *parent, struct cfdata *match, void *aux)
{
struct pci_attach_args *pa = aux;
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)
== 0)
return 0;
return 1;
}
int
agp_sis_attach(struct device *parent, struct device *self, void *aux)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: agp_via.c,v 1.1 2001/09/10 10:01:02 fvdl Exp $ */
/* $NetBSD: agp_via.c,v 1.2 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -71,18 +71,6 @@ struct agp_via_softc {
struct agp_gatt *gatt;
};
int
agp_via_match(struct device *parent, struct cfdata *match, void *aux)
{
struct pci_attach_args *pa = aux;
if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL)
== 0)
return 0;
return 1;
}
int
agp_via_attach(struct device *parent, struct device *self, void *aux)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: agpvar.h,v 1.2 2001/09/11 06:51:47 fvdl Exp $ */
/* $NetBSD: agpvar.h,v 1.3 2001/09/15 00:25:00 thorpej Exp $ */
/*-
* Copyright (c) 2000 Doug Rabson
@ -33,8 +33,8 @@
#include <sys/lock.h>
struct agp_phcb_attach_args {
char *apa_busname; /* XXX layout compat with pcibus_attach_args */
struct agpbus_attach_args {
char *apa_busname;
struct pci_attach_args apa_pci_args;
};
@ -182,13 +182,7 @@ int agp_generic_bind_memory(struct agp_softc *sc, struct agp_memory *mem,
int agp_generic_unbind_memory(struct agp_softc *sc, struct agp_memory *mem);
/* The vendor has already been matched when these functions are called */
int agp_ali_match(struct device *, struct cfdata *, void *);
int agp_amd_match(struct device *, struct cfdata *, void *);
int agp_i810_match(struct device *, struct cfdata *, void *);
int agp_i810_bridgematch(struct pci_attach_args *);
int agp_intel_match(struct device *, struct cfdata *, void *);
int agp_sis_match(struct device *, struct cfdata *, void *);
int agp_via_match(struct device *, struct cfdata *, void *);
int agp_amd_match(const struct pci_attach_args *);
int agp_ali_attach(struct device *parent, struct device *self, void *aux);
int agp_amd_attach(struct device *parent, struct device *self, void *aux);