Author: jhb
Date: Fri Jun 17 21:19:01 2011
New Revision: 223207
URL: http://svn.freebsd.org/changeset/base/223207

Log:
  Don't create a device_t object or parse current resources (via _CRS) for
  ACPI Device() objects that do not have any device IDs available via the
  _HID or _CID methods.  Without a device ID a device driver cannot attach
  to the device anyway.  Namespace objects that are devices but not of
  type ACPI_TYPE_DEVICE are not affected.
  
  A few BIOSes have also attached a _CRS method to a PCI device to
  allocate resources that are not managed via a BAR.  With the previous
  code those resources are allocated from acpi0 directly which can interfere
  with the new PCI-PCI bridge driver (since the PCI device in question may
  be behind a bridge and its resources should be allocated from that
  bridge's windows instead).  The resources were also orphaned and
  and would end up associated with some other random device whose device_t
  reused the pointer of the original ACPI-enumerated device (after it was
  free'd by the ACPI PCI bus driver) in devinfo output which was confusing.
  If we want to handle _CRS on PCI devices we can adjust the ACPI PCI bus
  driver to do that in the future and associate the resources with the
  proper device object respecting PCI-PCI bridges, etc.
  
  Note that with this change the ACPI PCI bus driver no longer has to
  delete ACPI-enumerated device_t devices that mirror PCI devices since
  they should in general not exist.  There are rare cases when a BIOS
  will give a PCI device a _HID (e.g. I've seen a PCI-ISA bridge given
  a _HID for a system resource device).  In that case we leave both the
  ACPI and PCI-enumerated device_t objects around just as in the previous
  code.

Modified:
  head/sys/dev/acpica/acpi.c
  head/sys/dev/acpica/acpi_pci.c

Modified: head/sys/dev/acpica/acpi.c
==============================================================================
--- head/sys/dev/acpica/acpi.c  Fri Jun 17 21:16:27 2011        (r223206)
+++ head/sys/dev/acpica/acpi.c  Fri Jun 17 21:19:01 2011        (r223207)
@@ -151,6 +151,7 @@ static ACPI_STATUS acpi_sleep_disable(st
 static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state);
 static void    acpi_shutdown_final(void *arg, int howto);
 static void    acpi_enable_fixed_events(struct acpi_softc *sc);
+static BOOLEAN acpi_has_hid(ACPI_HANDLE handle);
 static int     acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate);
 static int     acpi_wake_run_prep(ACPI_HANDLE handle, int sstate);
 static int     acpi_wake_prep_walk(int sstate);
@@ -1855,6 +1856,13 @@ acpi_probe_child(ACPI_HANDLE handle, UIN
                break;
            if (acpi_parse_prw(handle, &prw) == 0)
                AcpiSetupGpeForWake(handle, prw.gpe_handle, prw.gpe_bit);
+
+           /*
+            * Ignore devices that do not have a _HID or _CID.  They should
+            * be discovered by other buses (e.g. the PCI bus driver).
+            */
+           if (!acpi_has_hid(handle))
+               break;
            /* FALLTHROUGH */
        case ACPI_TYPE_PROCESSOR:
        case ACPI_TYPE_THERMAL:
@@ -2043,6 +2051,30 @@ acpi_BatteryIsPresent(device_t dev)
 }
 
 /*
+ * Returns true if a device has at least one valid device ID.
+ */
+static BOOLEAN
+acpi_has_hid(ACPI_HANDLE h)
+{
+    ACPI_DEVICE_INFO   *devinfo;
+    BOOLEAN            ret;
+
+    if (h == NULL ||
+       ACPI_FAILURE(AcpiGetObjectInfo(h, &devinfo)))
+       return (FALSE);
+
+    ret = FALSE;
+    if ((devinfo->Valid & ACPI_VALID_HID) != 0)
+       ret = TRUE;
+    else if ((devinfo->Valid & ACPI_VALID_CID) != 0)
+       if (devinfo->CompatibleIdList.Count > 0)
+           ret = TRUE;
+
+    AcpiOsFree(devinfo);
+    return (ret);
+}
+
+/*
  * Match a HID string against a handle
  */
 BOOLEAN

Modified: head/sys/dev/acpica/acpi_pci.c
==============================================================================
--- head/sys/dev/acpica/acpi_pci.c      Fri Jun 17 21:16:27 2011        
(r223206)
+++ head/sys/dev/acpica/acpi_pci.c      Fri Jun 17 21:19:01 2011        
(r223207)
@@ -209,38 +209,24 @@ acpi_pci_update_device(ACPI_HANDLE handl
        device_t child;
 
        /*
-        * Lookup and remove the unused device that acpi0 creates when it walks
-        * the namespace creating devices.
+        * Occasionally a PCI device may show up as an ACPI device
+        * with a _HID.  (For example, the TabletPC TC1000 has a
+        * second PCI-ISA bridge that has a _HID for an
+        * acpi_sysresource device.)  In that case, leave ACPI-CA's
+        * device data pointing at the ACPI-enumerated device.
         */
        child = acpi_get_device(handle);
        if (child != NULL) {
-               if (device_is_alive(child)) {
-                       /*
-                        * The TabletPC TC1000 has a second PCI-ISA bridge
-                        * that has a _HID for an acpi_sysresource device.
-                        * In that case, leave ACPI-CA's device data pointing
-                        * at the ACPI-enumerated device.
-                        */
-                       device_printf(child,
-                           "Conflicts with PCI device %d:%d:%d\n",
-                           pci_get_bus(pci_child), pci_get_slot(pci_child),
-                           pci_get_function(pci_child));
-                       return;
-               }
                KASSERT(device_get_parent(child) ==
                    devclass_get_device(devclass_find("acpi"), 0),
                    ("%s: child (%s)'s parent is not acpi0", __func__,
                    acpi_name(handle)));
-               device_delete_child(device_get_parent(child), child);
+               return;
        }
 
        /*
         * Update ACPI-CA to use the PCI enumerated device_t for this handle.
         */
-       status = AcpiDetachData(handle, acpi_fake_objhandler);
-       if (ACPI_FAILURE(status))
-               printf("WARNING: Unable to detach object data from %s - %s\n",
-                   acpi_name(handle), AcpiFormatException(status));
        status = AcpiAttachData(handle, acpi_fake_objhandler, pci_child);
        if (ACPI_FAILURE(status))
                printf("WARNING: Unable to attach object data to %s - %s\n",
_______________________________________________
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