svn commit: r194294 - in stable/7/sys: . contrib/pf dev/acpica dev/ath/ath_hal

John Baldwin jhb at FreeBSD.org
Tue Jun 16 15:09:18 UTC 2009


Author: jhb
Date: Tue Jun 16 15:09:17 2009
New Revision: 194294
URL: http://svn.freebsd.org/changeset/base/194294

Log:
  MFC: Rework the _BBN handling for Host-PCI bridges to always trust the
  first bus that claims to be bus 0.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/acpica/acpi_pcib_acpi.c
  stable/7/sys/dev/ath/ath_hal/   (props changed)

Modified: stable/7/sys/dev/acpica/acpi_pcib_acpi.c
==============================================================================
--- stable/7/sys/dev/acpica/acpi_pcib_acpi.c	Tue Jun 16 14:55:13 2009	(r194293)
+++ stable/7/sys/dev/acpica/acpi_pcib_acpi.c	Tue Jun 16 15:09:17 2009	(r194294)
@@ -145,6 +145,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;
     uint8_t busno;
 
@@ -155,6 +156,21 @@ acpi_pcib_acpi_attach(device_t dev)
     sc->ap_handle = acpi_get_handle(dev);
 
     /*
+     * 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);
+    if (ACPI_FAILURE(status)) {
+	if (status != AE_NOT_FOUND) {
+	    device_printf(dev, "could not evaluate _SEG - %s\n",
+		AcpiFormatException(status));
+	    return_VALUE (ENXIO);
+	}
+	/* If it's not found, assume 0. */
+	sc->ap_segment = 0;
+    }
+
+    /*
      * Get our base bus number by evaluating _BBN.
      * If this doesn't work, we assume we're bus number 0.
      *
@@ -168,8 +184,10 @@ acpi_pcib_acpi_attach(device_t dev)
      * XXX invoke _REG on this for the PCI config space address space?
      * XXX It seems many BIOS's with multiple Host-PCI bridges do not set
      *     _BBN correctly.  They set _BBN to zero for all bridges.  Thus,
-     *     if _BBN is zero and pcib0 already exists, we try to read our
+     *     if _BBN is zero and PCI bus 0 already exists, we try to read our
      *     bus number from the configuration registers at address _ADR.
+     *     We only do this for domain/segment 0 in the hopes that this is
+     *     only needed for old single-domain machines.
      */
     status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus);
     if (ACPI_FAILURE(status)) {
@@ -184,11 +202,11 @@ acpi_pcib_acpi_attach(device_t dev)
     }
 
     /*
-     * If the bus is zero and pcib0 already exists, read the bus number
-     * via PCI config space.
+     * If this is segment 0, the bus is zero, and PCI bus 0 already
+     * exists, read the bus number via PCI config space.
      */
     busok = 1;
-    if (sc->ap_bus == 0 && devclass_get_device(pcib_devclass, 0) != dev) {
+    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)) {
@@ -225,20 +243,9 @@ acpi_pcib_acpi_attach(device_t dev)
 	device_printf(dev, "trying bus number %d\n", sc->ap_bus);
     }
 
-    /*
-     * 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);
-    if (ACPI_FAILURE(status)) {
-	if (status != AE_NOT_FOUND) {
-	    device_printf(dev, "could not evaluate _SEG - %s\n",
-		AcpiFormatException(status));
-	    return_VALUE (ENXIO);
-	}
-	/* If it's not found, assume 0. */
-	sc->ap_segment = 0;
-    }
+    /* If this is bus 0 on segment 0, note that it has been seen already. */
+    if (sc->ap_segment == 0 && sc->ap_bus == 0)
+	    bus0_seen = 1;
 
     return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
 }


More information about the svn-src-stable mailing list