diff options
author | marius <marius@FreeBSD.org> | 2013-03-01 20:34:02 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2013-03-01 20:34:02 +0000 |
commit | 944a48f5cd4b3de81295d4b289362610ee533cd2 (patch) | |
tree | e4a1d1dc7c50fc36fdaa1ed0ae4e463a455c7d72 /sys/sparc64 | |
parent | 8e8db171cbe74d53a2ad5144bc9a8bfcfad26b42 (diff) | |
download | FreeBSD-src-944a48f5cd4b3de81295d4b289362610ee533cd2.zip FreeBSD-src-944a48f5cd4b3de81295d4b289362610ee533cd2.tar.gz |
- Remove an unused header.
- Use NULL instead of 0 for pointers.
- Let ofw_pcib_probe() return BUS_PROBE_DEFAULT instead of 0 so specialized
PCI-PCI-bridge drivers may attach instead.
- Add WARs for PLX Technology PEX 8114 bridges and PEX 8532 switches.
Ideally, these should live in MI code but at least for the latter we're
missing the necessary infrastructure there.
MFC after: 1 week
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/pci/ofw_pcib.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/sys/sparc64/pci/ofw_pcib.c b/sys/sparc64/pci/ofw_pcib.c index 69bdb72..7944237 100644 --- a/sys/sparc64/pci/ofw_pcib.c +++ b/sys/sparc64/pci/ofw_pcib.c @@ -47,8 +47,6 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/ofw_bus.h> #include <dev/ofw/openfirm.h> -#include <machine/bus.h> - #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcib_private.h> @@ -58,8 +56,12 @@ __FBSDID("$FreeBSD$"); #include <sparc64/pci/ofw_pci.h> #include <sparc64/pci/ofw_pcib_subr.h> +#define PCI_DEVID_ALI_M5249 0x524910b9 +#define PCI_VENDOR_PLX 0x10b5 + static device_probe_t ofw_pcib_probe; static device_attach_t ofw_pcib_attach; +static ofw_pci_setup_device_t ofw_pcib_setup_device; static device_method_t ofw_pcib_methods[] = { /* Device interface */ @@ -73,6 +75,7 @@ static device_method_t ofw_pcib_methods[] = { /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, ofw_pcib_gen_get_node), + DEVMETHOD(ofw_pci_setup_device, ofw_pcib_setup_device), DEVMETHOD_END }; @@ -81,7 +84,7 @@ static devclass_t pcib_devclass; DEFINE_CLASS_1(pcib, ofw_pcib_driver, ofw_pcib_methods, sizeof(struct ofw_pcib_gen_softc), pcib_driver); -EARLY_DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, 0, 0, +EARLY_DRIVER_MODULE(ofw_pcib, pci, ofw_pcib_driver, pcib_devclass, NULL, NULL, BUS_PASS_BUS); MODULE_DEPEND(ofw_pcib, pci, 1, 1, 1); @@ -104,7 +107,7 @@ ofw_pcib_probe(device_t dev) ISDTYPE(pbdtype, OFW_TYPE_PCIE) ? "e" : "", ISDTYPE(dtype, OFW_TYPE_PCIE) ? "e" : ""); device_set_desc_copy(dev, desc); - return (0); + return (BUS_PROBE_DEFAULT); } #undef ISDTYPE @@ -119,7 +122,6 @@ ofw_pcib_attach(device_t dev) sc = device_get_softc(dev); - /* Quirk handling */ switch (pci_get_devid(dev)) { /* * The ALi M5249 found in Fire-based machines by definition must me @@ -127,13 +129,46 @@ ofw_pcib_attach(device_t dev) * don't indicate this in the class code although the ISA I/O range * isn't included in their bridge decode. */ - case 0x524910b9: + case PCI_DEVID_ALI_M5249: sc->ops_pcib_sc.flags |= PCIB_SUBTRACTIVE; break; } + switch (pci_get_vendor(dev)) { + /* + * Concurrently write the primary and secondary bus numbers in order + * to work around a bug in PLX PEX 8114 causing the internal shadow + * copies of these not to be updated when setting them bytewise. + */ + case PCI_VENDOR_PLX: + pci_write_config(dev, PCIR_PRIBUS_1, + pci_read_config(dev, PCIR_SECBUS_1, 1) << 8 | + pci_read_config(dev, PCIR_PRIBUS_1, 1), 2); + break; + } + ofw_pcib_gen_setup(dev); pcib_attach_common(dev); device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } + +static void +ofw_pcib_setup_device(device_t bus, device_t child) +{ + int i; + uint16_t reg; + + switch (pci_get_vendor(bus)) { + /* + * For PLX PEX 8532 issue 64 TLPs to the child from the downstream + * port to the child device in order to work around a hardware bug. + */ + case PCI_VENDOR_PLX: + for (i = 0, reg = 0; i < 64; i++) + reg |= pci_get_devid(child); + break; + } + + OFW_PCI_SETUP_DEVICE(device_get_parent(bus), child); +} |