Author: marcel
Date: Mon Feb  1 17:51:01 2010
New Revision: 203352
URL: http://svn.freebsd.org/changeset/base/203352

Log:
  Make PCI Express host controllers functional, by:
  1.  checking whether there's a link before initializing devices
      on the bus. When there's no link any access onto the bus
      will wedge the CPU.
  2.  synthesizing the class & subclass so that the host controller
      appears as a standard PCI bridge, rather than a PowerPC CPU.

Modified:
  head/sys/powerpc/mpc85xx/pci_ocp.c

Modified: head/sys/powerpc/mpc85xx/pci_ocp.c
==============================================================================
--- head/sys/powerpc/mpc85xx/pci_ocp.c  Mon Feb  1 17:36:48 2010        
(r203351)
+++ head/sys/powerpc/mpc85xx/pci_ocp.c  Mon Feb  1 17:51:01 2010        
(r203352)
@@ -76,6 +76,9 @@ __FBSDID("$FreeBSD$");
 #define        REG_PIWBEAR(n)  (0x0e0c - 0x20 * (n))
 #define        REG_PIWAR(n)    (0x0e10 - 0x20 * (n))
 
+#define        PCIR_FSL_LTSSM  0x404
+#define        FSL_LTSSM_L0    0x16
+
 #define        DEVFN(b, s, f)  ((b << 16) | (s << 8) | f)
 
 struct pci_ocp_softc {
@@ -274,6 +277,18 @@ pci_ocp_read_config(device_t dev, u_int 
        if (bus == sc->sc_busnr && !sc->sc_pcie_cap && slot < 10)
                return (~0);
        devfn = DEVFN(bus, slot, func);
+       /*
+        * For the host controller itself, pretend to be a standard
+        * PCI bridge, rather than a PowerPC processor. That way the
+        * generic PCI code will enumerate all subordinate busses
+        * and devices as usual.
+        */
+       if (sc->sc_pcie_cap && devfn == 0) {
+               if (reg == PCIR_CLASS && bytes == 1)
+                       return (PCIC_BRIDGE);
+               if (reg == PCIR_SUBCLASS && bytes == 1)
+                       return (PCIS_BRIDGE_PCI);
+       }
        if (devfn == sc->sc_devfn_tundra)
                return (~0);
        if (devfn == sc->sc_devfn_via_ide && reg == PCIR_INTPIN)
@@ -739,6 +754,17 @@ pci_ocp_attach(device_t dev)
        sc->sc_devfn_tundra = -1;
        sc->sc_devfn_via_ide = -1;
 
+       /*
+        * PCI Express host controllers require a link. We don't
+        * fail the attach if there's no link, but we also don't
+        * create a child pci(4) device.
+        */
+       if (sc->sc_pcie_cap) {
+               cfgreg = pci_ocp_cfgread(sc, 0, 0, 0, PCIR_FSL_LTSSM, 4);
+               if (cfgreg < FSL_LTSSM_L0)
+                       return (0);
+       }
+
        maxslot = (sc->sc_pcie_cap) ? 1 : 31;
        pci_ocp_init(sc, sc->sc_busnr, maxslot);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to