diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-03-19 02:43:39 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-03-19 02:43:39 +0000 |
commit | 2de1e0f40803f7f0de26e365f0c02a0b4cc4d330 (patch) | |
tree | e187e02df86e3a0e9b6c58f465d0407f474a2150 /sys/arch | |
parent | 4cc27836a57fbda13281aa7986a92b1f641e3181 (diff) |
rev 1.86
make the "generic" PCI bus enumeration code the standard case which
gets used if nothing else is defined in MD headers,
introduce a "PCI_MACHDEP_ENUMERATE_BUS" CPP definition which can
be used by MD headers (just 1 port atm) to plug in special code
rev 1.62
* Implement a machine-dependent pci_enumerate_bus() for sparc64 which
uses OFW device nodes to enumerate the bus. When a PCI bus that is
behind a bridge is attached, pci_attach_hook() allocates a new PCI
chipset tag for the new bus and sets it's "curnode" to the OFW node
of the bridge. This is used as a starting point when enumerating
that bus. Root busses get the OFW node of the host bridge (psycho).
rev 1.59
Split the code that enumerates the PCI bus and that actually probes
for a device into two functions:
* pci_probe_device() actually probes/attaches the device specified
by the provide pcitag_t.
* pci_enumerate_bus() enumerates the bus, and calls pci_probe_device()
for each device on the bus. A pci_enumerate_bus_generic() is provided
which implements the old method of doing this: If something found at
dev0/func0, determine number of functions and probe each one.
From NetBSD
ok kettenis@
Tested on a good number of amd64/i386/macppc/sparc64 systems
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sparc64/dev/pci_machdep.c | 197 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/psycho.c | 3 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizo.c | 3 | ||||
-rw-r--r-- | sys/arch/sparc64/include/pci_machdep.h | 21 |
4 files changed, 72 insertions, 152 deletions
diff --git a/sys/arch/sparc64/dev/pci_machdep.c b/sys/arch/sparc64/dev/pci_machdep.c index 7b7c6469a75..2582d98aefc 100644 --- a/sys/arch/sparc64/dev/pci_machdep.c +++ b/sys/arch/sparc64/dev/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.21 2006/01/06 20:30:09 kettenis Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.22 2006/03/19 02:43:38 brad Exp $ */ /* $NetBSD: pci_machdep.c,v 1.22 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -37,7 +37,6 @@ #define SPDB_CONF 0x01 #define SPDB_INTR 0x04 #define SPDB_INTMAP 0x08 -#define SPDB_INTFIX 0x10 #define SPDB_PROBE 0x20 int sparc_pci_debug = 0x0; #define DPRINTF(l, s) do { if (sparc_pci_debug & l) printf s; } while (0) @@ -73,6 +72,21 @@ struct sparc_pci_chipset _sparc_pci_chipset = { NULL, }; +static pcitag_t +ofpci_make_tag(pci_chipset_tag_t pc, int node, int b, int d, int f) +{ + pcitag_t tag; + + tag = PCITAG_CREATE(node, b, d, f); + + /* Enable all the different spaces for this device */ + pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, + PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE| + PCI_COMMAND_IO_ENABLE); + + return (tag); +} + /* * functions provided to the MI code. */ @@ -95,124 +109,6 @@ pci_bus_maxdevs(pc, busno) return 32; } -#ifdef __PCI_BUS_DEVORDER -int -pci_bus_devorder(pc, busno, devs) - pci_chipset_tag_t pc; - int busno; - char *devs; -{ - struct ofw_pci_register reg; - int node, len, device, i = 0; - u_int32_t done = 0; -#ifdef DEBUG - char name[80]; -#endif - - node = pc->curnode; -#ifdef DEBUG - if (sparc_pci_debug & SPDB_PROBE) { - OF_getprop(node, "name", &name, sizeof(name)); - printf("pci_bus_devorder: curnode %x %s\n", node, name); - } -#endif - /* - * Initially, curnode is the root of the pci tree. As we - * attach bridges, curnode should be set to that of the bridge. - */ - for (node = OF_child(node); node; node = OF_peer(node)) { - len = OF_getproplen(node, "reg"); - if (len < sizeof(reg)) - continue; - if (OF_getprop(node, "reg", (void *)®, sizeof(reg)) != len) - panic("pci_probe_bus: OF_getprop len botch"); - - device = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi); - - if (done & (1 << device)) - continue; - - devs[i++] = device; - done |= 1 << device; -#ifdef DEBUG - if (sparc_pci_debug & SPDB_PROBE) { - OF_getprop(node, "name", &name, sizeof(name)); - printf("pci_bus_devorder: adding %x %s\n", node, name); - } -#endif - if (i == 32) - break; - } - if (i < 32) - devs[i] = -1; - - return i; -} -#endif - -#ifdef __PCI_DEV_FUNCORDER -int -pci_dev_funcorder(pc, busno, device, funcs) - pci_chipset_tag_t pc; - int busno; - int device; - char *funcs; -{ - struct ofw_pci_register reg; - int node, len, function, i = 0; - u_int8_t done = 0; -#ifdef DEBUG - char name[80]; -#endif - - node = pc->curnode; -#ifdef DEBUG - if (sparc_pci_debug & SPDB_PROBE) { - OF_getprop(node, "name", &name, sizeof(name)); - printf("pci_bus_funcorder: curnode %x %s\n", node, name); - } -#endif - /* - * Functions are siblings. Presumably we're only called when the - * first instance of this device is detected, so we should be able to - * get to all the other functions with OF_peer(). But there seems - * some issues with this scheme, so we always go to the first node on - * this bus segment for a scan. - */ - for (node = OF_child(OF_parent(node)); node; node = OF_peer(node)) { - len = OF_getproplen(node, "reg"); - if (len < sizeof(reg)) - continue; - if (OF_getprop(node, "reg", (void *)®, sizeof(reg)) != len) - panic("pci_probe_bus: OF_getprop len botch"); - - if (device != OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi)) - continue; - - - function = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi); - - if (done & (1 << function)) - continue; - - funcs[i++] = function; - done |= 1 << function; -#ifdef DEBUG - if (sparc_pci_debug & SPDB_PROBE) { - OF_getprop(node, "name", &name, sizeof(name)); - printf("pci_bus_funcorder: adding %x %s\n", node, name); - } -#endif - if (i == 8) - break; - } - if (i < 8) - funcs[i] = -1; - - return i; -} -#endif - pcitag_t pci_make_tag(pc, b, d, f) pci_chipset_tag_t pc; @@ -323,21 +219,8 @@ pci_make_tag(pc, b, d, f) continue; /* Got a match */ - tag = PCITAG_CREATE(node, b, d, f); - - /* - * Record the node. This has two effects: - * - * 1) We don't have to search as far. - * 2) pci_bus_devorder will scan the right bus. - */ - pc->curnode = node; + tag = ofpci_make_tag(pc, node, b, d, f); - /* Enable all the different spaces for this device */ - pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, - PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE| - PCI_COMMAND_IO_ENABLE); - DPRINTF(SPDB_PROBE, ("found node %x %s\n", node, name)); return (tag); } /* No device found -- return a dead tag */ @@ -359,6 +242,52 @@ pci_decompose_tag(pc, tag, bp, dp, fp) *fp = PCITAG_FUN(tag); } +int +sparc64_pci_enumerate_bus(struct pci_softc *sc, + int (*match)(struct pci_attach_args *), struct pci_attach_args *pap) +{ + struct ofw_pci_register reg; + pci_chipset_tag_t pc = sc->sc_pc; + pcitag_t tag; + pcireg_t class; + int node, b, d, f, ret; + char name[30]; + + if (sc->sc_bridgetag) + node = PCITAG_NODE(*sc->sc_bridgetag); + else + node = pc->rootnode; + + for (node = OF_child(node); node != 0 && node != -1; + node = OF_peer(node)) { + name[0] = name[29] = 0; + OF_getprop(node, "name", name, sizeof(name)); + + if (OF_getprop(node, "class-code", &class, sizeof(class)) != + sizeof(class)) + continue; + if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) + panic("pci_enumerate_bus: \"%s\" regs too small", name); + + b = OFW_PCI_PHYS_HI_BUS(reg.phys_hi); + d = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi); + f = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi); + + if (sc->sc_bus != b) { + printf("%s: WARNING: incorrect bus # for \"%s\" " + "(%d/%d/%d)\n", sc->sc_dev.dv_xname, name, b, d, f); + continue; + } + + tag = ofpci_make_tag(pc, node, b, d, f); + ret = pci_probe_device(sc, tag, match, pap); + if (match != NULL && ret != 0) + return (ret); + } + + return (0); +} + /* assume we are mapped little-endian/side-effect */ pcireg_t pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index b187a7e81c7..0f3defc211d 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psycho.c,v 1.42 2006/03/13 20:10:49 brad Exp $ */ +/* $OpenBSD: psycho.c,v 1.43 2006/03/19 02:43:38 brad Exp $ */ /* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -650,7 +650,6 @@ psycho_alloc_chipset(struct psycho_pbm *pp, int node, pci_chipset_tag_t pc) memcpy(npc, pc, sizeof *pc); npc->cookie = pp; npc->rootnode = node; - npc->curnode = node; return (npc); } diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c index 252275b7eba..2a3b0800300 100644 --- a/sys/arch/sparc64/dev/schizo.c +++ b/sys/arch/sparc64/dev/schizo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schizo.c,v 1.17 2006/03/13 20:10:49 brad Exp $ */ +/* $OpenBSD: schizo.c,v 1.18 2006/03/19 02:43:38 brad Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -347,7 +347,6 @@ schizo_alloc_chipset(struct schizo_pbm *pbm, int node, pci_chipset_tag_t pc) memcpy(npc, pc, sizeof *pc); npc->cookie = pbm; npc->rootnode = node; - npc->curnode = node; return (npc); } diff --git a/sys/arch/sparc64/include/pci_machdep.h b/sys/arch/sparc64/include/pci_machdep.h index e9148812ebf..ddbc74de461 100644 --- a/sys/arch/sparc64/include/pci_machdep.h +++ b/sys/arch/sparc64/include/pci_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.h,v 1.14 2005/09/04 20:40:53 brad Exp $ */ +/* $OpenBSD: pci_machdep.h,v 1.15 2006/03/19 02:43:38 brad Exp $ */ /* $NetBSD: pci_machdep.h,v 1.7 2001/07/20 00:07:14 eeh Exp $ */ /* @@ -33,12 +33,6 @@ #define _MACHINE_PCI_MACHDEP_H_ /* - * We want to control both device & function probe order. - */ -#define __PCI_BUS_DEVORDER -#define __PCI_DEV_FUNCORDER - -/* * Forward declarations. */ struct pci_attach_args; @@ -73,18 +67,11 @@ struct sparc_pci_chipset { bus_space_tag_t bustag; bus_space_handle_t bushandle; int rootnode; /* PCI controller */ - int curnode; /* Current OFW node */ int (*intr_map)(struct pci_attach_args *, pci_intr_handle_t *); }; void pci_attach_hook(struct device *, struct device *, struct pcibus_attach_args *); -#ifdef __PCI_BUS_DEVORDER -int pci_bus_devorder(pci_chipset_tag_t, int, char *); -#endif -#ifdef __PCI_DEV_FUNCORDER -int pci_dev_funcorder(pci_chipset_tag_t, int, int, char *); -#endif int pci_bus_maxdevs(pci_chipset_tag_t, int); pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int); void pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *, @@ -98,6 +85,12 @@ void *pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t, int, int (*)(void *), void *, char *); void pci_intr_disestablish(pci_chipset_tag_t, void *); +int sparc64_pci_enumerate_bus(struct pci_softc *, + int (*match)(struct pci_attach_args *), + struct pci_attach_args *); + +#define PCI_MACHDEP_ENUMERATE_BUS sparc64_pci_enumerate_bus + #define pciide_machdep_compat_intr_establish(a, b, c, d, e) (NULL) #define pciide_machdep_compat_intr_disestablish(a, b) do { } while (0) |