Author: jhb
Date: Wed Apr 11 20:50:17 2012
New Revision: 234150
URL: http://svn.freebsd.org/changeset/base/234150

Log:
  MFC 233676:
  Use a more proper fix for enabling HT MSI mapping windows on Host-PCI
  bridges.  Rather than blindly enabling the windows on all of them, only
  enable the window when an MSI interrupt is enabled for a device behind
  the bridge, similar to what already happens for HT PCI-PCI bridges.

Modified:
  stable/9/sys/amd64/amd64/legacy.c
  stable/9/sys/amd64/include/legacyvar.h
  stable/9/sys/dev/acpica/acpi_pcib_acpi.c
  stable/9/sys/dev/pci/pci.c
  stable/9/sys/i386/i386/legacy.c
  stable/9/sys/i386/include/legacyvar.h
  stable/9/sys/x86/pci/pci_bus.c
  stable/9/sys/x86/x86/mptable_pci.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)
  stable/9/sys/fs/   (props changed)
  stable/9/sys/fs/ntfs/   (props changed)
  stable/9/sys/i386/conf/XENHVM   (props changed)
  stable/9/sys/kern/subr_witness.c   (props changed)

Modified: stable/9/sys/amd64/amd64/legacy.c
==============================================================================
--- stable/9/sys/amd64/amd64/legacy.c   Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/amd64/amd64/legacy.c   Wed Apr 11 20:50:17 2012        
(r234150)
@@ -53,7 +53,9 @@ __FBSDID("$FreeBSD$");
 
 static MALLOC_DEFINE(M_LEGACYDEV, "legacydrv", "legacy system device");
 struct legacy_device {
-       int                     lg_pcibus;
+       int     lg_pcibus;
+       int     lg_pcislot;
+       int     lg_pcifunc;
 };
 
 #define DEVTOAT(dev)   ((struct legacy_device *)device_get_ivars(dev))
@@ -161,6 +163,8 @@ legacy_add_child(device_t bus, u_int ord
        if (atdev == NULL)
                return(NULL);
        atdev->lg_pcibus = -1;
+       atdev->lg_pcislot = -1;
+       atdev->lg_pcifunc = -1;
 
        child = device_add_child_ordered(bus, order, name, unit);
        if (child == NULL)
@@ -184,6 +188,12 @@ legacy_read_ivar(device_t dev, device_t 
        case LEGACY_IVAR_PCIBUS:
                *result = atdev->lg_pcibus;
                break;
+       case LEGACY_IVAR_PCISLOT:
+               *result = atdev->lg_pcislot;
+               break;
+       case LEGACY_IVAR_PCIFUNC:
+               *result = atdev->lg_pcifunc;
+               break;
        default:
                return ENOENT;
        }
@@ -202,6 +212,12 @@ legacy_write_ivar(device_t dev, device_t
        case LEGACY_IVAR_PCIBUS:
                atdev->lg_pcibus = value;
                break;
+       case LEGACY_IVAR_PCISLOT:
+               atdev->lg_pcislot = value;
+               break;
+       case LEGACY_IVAR_PCIFUNC:
+               atdev->lg_pcifunc = value;
+               break;
        default:
                return ENOENT;
        }

Modified: stable/9/sys/amd64/include/legacyvar.h
==============================================================================
--- stable/9/sys/amd64/include/legacyvar.h      Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/amd64/include/legacyvar.h      Wed Apr 11 20:50:17 2012        
(r234150)
@@ -31,7 +31,9 @@
 
 enum legacy_device_ivars {
        LEGACY_IVAR_PCIDOMAIN,
-       LEGACY_IVAR_PCIBUS
+       LEGACY_IVAR_PCIBUS,
+       LEGACY_IVAR_PCISLOT,
+       LEGACY_IVAR_PCIFUNC
 };
 
 #define LEGACY_ACCESSOR(var, ivar, type)                               \
@@ -39,6 +41,8 @@ enum legacy_device_ivars {
 
 LEGACY_ACCESSOR(pcidomain,             PCIDOMAIN,      uint32_t)
 LEGACY_ACCESSOR(pcibus,                        PCIBUS,         uint32_t)
+LEGACY_ACCESSOR(pcislot,               PCISLOT,        int)
+LEGACY_ACCESSOR(pcifunc,               PCIFUNC,        int)
 
 #undef LEGACY_ACCESSOR
 
@@ -53,5 +57,7 @@ int   legacy_pcib_write_ivar(device_t dev,
     uintptr_t value);
 struct resource *legacy_pcib_alloc_resource(device_t dev, device_t child,
     int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
+int    legacy_pcib_map_msi(device_t pcib, device_t dev, int irq,
+    uint64_t *addr, uint32_t *data);
 
 #endif /* !_MACHINE_LEGACYVAR_H_ */

Modified: stable/9/sys/dev/acpica/acpi_pcib_acpi.c
==============================================================================
--- stable/9/sys/dev/acpica/acpi_pcib_acpi.c    Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/dev/acpica/acpi_pcib_acpi.c    Wed Apr 11 20:50:17 2012        
(r234150)
@@ -59,8 +59,9 @@ struct acpi_hpcib_softc {
     ACPI_HANDLE                ap_handle;
     int                        ap_flags;
 
-    int                        ap_segment;     /* analagous to Alpha 'hose' */
+    int                        ap_segment;     /* PCI domain */
     int                        ap_bus;         /* bios-assigned bus number */
+    int                        ap_addr;        /* device/func of PCI-Host 
bridge */
 
     ACPI_BUFFER                ap_prt;         /* interrupt routing table */
 #ifdef NEW_PCIB
@@ -276,7 +277,7 @@ acpi_pcib_acpi_attach(device_t dev)
     struct acpi_hpcib_softc    *sc;
     ACPI_STATUS                        status;
     static int bus0_seen = 0;
-    u_int addr, slot, func, busok;
+    u_int slot, func, busok;
     uint8_t busno;
 
     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
@@ -286,7 +287,7 @@ acpi_pcib_acpi_attach(device_t dev)
     sc->ap_handle = acpi_get_handle(dev);
 
     /*
-     * Get our segment number by evaluating _SEG
+     * Get our segment number by evaluating _SEG.
      * It's OK for this to not exist.
      */
     status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment);
@@ -300,6 +301,18 @@ acpi_pcib_acpi_attach(device_t dev)
        sc->ap_segment = 0;
     }
 
+    /*
+     * Get the address (device and function) of the associated
+     * PCI-Host bridge device from _ADR.  Assume we don't have one if
+     * it doesn't exist.
+     */
+    status = acpi_GetInteger(sc->ap_handle, "_ADR", &sc->ap_addr);
+    if (ACPI_FAILURE(status)) {
+       device_printf(dev, "could not evaluate _ADR - %s\n",
+           AcpiFormatException(status));
+       sc->ap_addr = -1;
+    }
+
 #ifdef NEW_PCIB
     /*
      * Determine which address ranges this bridge decodes and setup
@@ -354,18 +367,10 @@ acpi_pcib_acpi_attach(device_t dev)
     busok = 1;
     if (sc->ap_segment == 0 && sc->ap_bus == 0 && bus0_seen) {
        busok = 0;
-       status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr);
-       if (ACPI_FAILURE(status)) {
-           if (status != AE_NOT_FOUND) {
-               device_printf(dev, "could not evaluate _ADR - %s\n",
-                   AcpiFormatException(status));
-               return_VALUE (ENXIO);
-           } else
-               device_printf(dev, "couldn't find _ADR\n");
-       } else {
+       if (sc->ap_addr != -1) {
            /* XXX: We assume bus 0. */
-           slot = ACPI_ADR_PCI_SLOT(addr);
-           func = ACPI_ADR_PCI_FUNC(addr);
+           slot = ACPI_ADR_PCI_SLOT(sc->ap_addr);
+           func = ACPI_ADR_PCI_FUNC(sc->ap_addr);
            if (bootverbose)
                device_printf(dev, "reading config registers from 0:%d:%d\n",
                    slot, func);
@@ -488,10 +493,24 @@ static int
 acpi_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
     uint32_t *data)
 {
-       device_t bus;
+       struct acpi_hpcib_softc *sc;
+       device_t bus, hostb;
+       int error;
 
        bus = device_get_parent(pcib);
-       return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
+       error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
+       if (error)
+               return (error);
+
+       sc = device_get_softc(dev);
+       if (sc->ap_addr == -1)
+               return (0);
+       /* XXX: Assumes all bridges are on bus 0. */
+       hostb = pci_find_dbsf(sc->ap_segment, 0, ACPI_ADR_PCI_SLOT(sc->ap_addr),
+           ACPI_ADR_PCI_FUNC(sc->ap_addr));
+       if (hostb != NULL)
+               pci_ht_map_msi(hostb, *addr);
+       return (0);
 }
 
 struct resource *

Modified: stable/9/sys/dev/pci/pci.c
==============================================================================
--- stable/9/sys/dev/pci/pci.c  Wed Apr 11 20:28:05 2012        (r234149)
+++ stable/9/sys/dev/pci/pci.c  Wed Apr 11 20:50:17 2012        (r234150)
@@ -756,7 +756,7 @@ pci_read_cap(device_t pcib, pcicfgregs *
                }
        }
 
-#if defined(__i386__) || defined(__amd64__) || defined(__powerpc__)
+#if defined(__powerpc__)
        /*
         * Enable the MSI mapping window for all HyperTransport
         * slaves.  PCI-PCI bridges have their windows enabled via

Modified: stable/9/sys/i386/i386/legacy.c
==============================================================================
--- stable/9/sys/i386/i386/legacy.c     Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/i386/i386/legacy.c     Wed Apr 11 20:50:17 2012        
(r234150)
@@ -58,7 +58,9 @@ __FBSDID("$FreeBSD$");
 
 static MALLOC_DEFINE(M_LEGACYDEV, "legacydrv", "legacy system device");
 struct legacy_device {
-       int                     lg_pcibus;
+       int     lg_pcibus;
+       int     lg_pcislot;
+       int     lg_pcifunc;
 };
 
 #define DEVTOAT(dev)   ((struct legacy_device *)device_get_ivars(dev))
@@ -182,6 +184,8 @@ legacy_add_child(device_t bus, u_int ord
        if (atdev == NULL)
                return(NULL);
        atdev->lg_pcibus = -1;
+       atdev->lg_pcislot = -1;
+       atdev->lg_pcifunc = -1;
 
        child = device_add_child_ordered(bus, order, name, unit);
        if (child == NULL)
@@ -205,6 +209,12 @@ legacy_read_ivar(device_t dev, device_t 
        case LEGACY_IVAR_PCIBUS:
                *result = atdev->lg_pcibus;
                break;
+       case LEGACY_IVAR_PCISLOT:
+               *result = atdev->lg_pcislot;
+               break;
+       case LEGACY_IVAR_PCIFUNC:
+               *result = atdev->lg_pcifunc;
+               break;
        default:
                return ENOENT;
        }
@@ -223,6 +233,12 @@ legacy_write_ivar(device_t dev, device_t
        case LEGACY_IVAR_PCIBUS:
                atdev->lg_pcibus = value;
                break;
+       case LEGACY_IVAR_PCISLOT:
+               atdev->lg_pcislot = value;
+               break;
+       case LEGACY_IVAR_PCIFUNC:
+               atdev->lg_pcifunc = value;
+               break;
        default:
                return ENOENT;
        }

Modified: stable/9/sys/i386/include/legacyvar.h
==============================================================================
--- stable/9/sys/i386/include/legacyvar.h       Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/i386/include/legacyvar.h       Wed Apr 11 20:50:17 2012        
(r234150)
@@ -31,7 +31,9 @@
 
 enum legacy_device_ivars {
        LEGACY_IVAR_PCIDOMAIN,
-       LEGACY_IVAR_PCIBUS
+       LEGACY_IVAR_PCIBUS,
+       LEGACY_IVAR_PCISLOT,
+       LEGACY_IVAR_PCIFUNC
 };
 
 #define LEGACY_ACCESSOR(var, ivar, type)                               \
@@ -39,6 +41,8 @@ enum legacy_device_ivars {
 
 LEGACY_ACCESSOR(pcidomain,             PCIDOMAIN,      uint32_t)
 LEGACY_ACCESSOR(pcibus,                        PCIBUS,         uint32_t)
+LEGACY_ACCESSOR(pcislot,               PCISLOT,        int)
+LEGACY_ACCESSOR(pcifunc,               PCIFUNC,        int)
 
 #undef LEGACY_ACCESSOR
 
@@ -53,5 +57,7 @@ int   legacy_pcib_write_ivar(device_t dev,
     uintptr_t value);
 struct resource *legacy_pcib_alloc_resource(device_t dev, device_t child,
     int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
+int    legacy_pcib_map_msi(device_t pcib, device_t dev, int irq,
+    uint64_t *addr, uint32_t *data);
 
 #endif /* !_MACHINE_LEGACYVAR_H_ */

Modified: stable/9/sys/x86/pci/pci_bus.c
==============================================================================
--- stable/9/sys/x86/pci/pci_bus.c      Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/x86/pci/pci_bus.c      Wed Apr 11 20:50:17 2012        
(r234150)
@@ -112,14 +112,28 @@ legacy_pcib_alloc_msix(device_t pcib, de
        return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
 }
 
-static int
+int
 legacy_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
     uint32_t *data)
 {
-       device_t bus;
+       device_t bus, hostb;
+       int error, func, slot;
 
        bus = device_get_parent(pcib);
-       return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
+       error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
+       if (error)
+               return (error);
+
+       slot = legacy_get_pcislot(pcib);
+       func = legacy_get_pcifunc(pcib);
+       if (slot == -1 || func == -1)
+               return (0);
+       hostb = pci_find_bsf(0, slot, func);
+       KASSERT(hostb != NULL, ("%s: missing hostb for 0:%d:%d", __func__,
+           slot, func));
+       pci_ht_map_msi(hostb, *addr);
+       return (0);
+       
 }
 
 static const char *
@@ -453,6 +467,8 @@ legacy_pcib_identify(driver_t *driver, d
                                              "pcib", busnum);
                        device_set_desc(child, s);
                        legacy_set_pcibus(child, busnum);
+                       legacy_set_pcislot(child, slot);
+                       legacy_set_pcifunc(child, func);
 
                        found = 1;
                        if (id == 0x12258086)

Modified: stable/9/sys/x86/x86/mptable_pci.c
==============================================================================
--- stable/9/sys/x86/x86/mptable_pci.c  Wed Apr 11 20:28:05 2012        
(r234149)
+++ stable/9/sys/x86/x86/mptable_pci.c  Wed Apr 11 20:50:17 2012        
(r234150)
@@ -97,16 +97,6 @@ mptable_hostb_alloc_msix(device_t pcib, 
        return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
 }
 
-static int
-mptable_hostb_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
-    uint32_t *data)
-{
-       device_t bus;
-
-       bus = device_get_parent(pcib);
-       return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
-}
-
 #ifdef NEW_PCIB
 static int
 mptable_is_isa_range(u_long start, u_long end)
@@ -214,7 +204,7 @@ static device_method_t mptable_hostb_met
        DEVMETHOD(pcib_release_msi,     pcib_release_msi),
        DEVMETHOD(pcib_alloc_msix,      mptable_hostb_alloc_msix),
        DEVMETHOD(pcib_release_msix,    pcib_release_msix),
-       DEVMETHOD(pcib_map_msi,         mptable_hostb_map_msi),
+       DEVMETHOD(pcib_map_msi,         legacy_pcib_map_msi),
 
        DEVMETHOD_END
 };
_______________________________________________
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