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.
This commit is contained in:
parent
edb18ee337
commit
da75fed86a
@ -151,6 +151,7 @@ static ACPI_STATUS acpi_sleep_disable(struct acpi_softc *sc);
|
|||||||
static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state);
|
static ACPI_STATUS acpi_EnterSleepState(struct acpi_softc *sc, int state);
|
||||||
static void acpi_shutdown_final(void *arg, int howto);
|
static void acpi_shutdown_final(void *arg, int howto);
|
||||||
static void acpi_enable_fixed_events(struct acpi_softc *sc);
|
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_sleep_prep(ACPI_HANDLE handle, int sstate);
|
||||||
static int acpi_wake_run_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);
|
static int acpi_wake_prep_walk(int sstate);
|
||||||
@ -1855,6 +1856,13 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
|
|||||||
break;
|
break;
|
||||||
if (acpi_parse_prw(handle, &prw) == 0)
|
if (acpi_parse_prw(handle, &prw) == 0)
|
||||||
AcpiSetupGpeForWake(handle, prw.gpe_handle, prw.gpe_bit);
|
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 */
|
/* FALLTHROUGH */
|
||||||
case ACPI_TYPE_PROCESSOR:
|
case ACPI_TYPE_PROCESSOR:
|
||||||
case ACPI_TYPE_THERMAL:
|
case ACPI_TYPE_THERMAL:
|
||||||
@ -2042,6 +2050,30 @@ acpi_BatteryIsPresent(device_t dev)
|
|||||||
return (present);
|
return (present);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Match a HID string against a handle
|
||||||
*/
|
*/
|
||||||
|
@ -209,38 +209,24 @@ acpi_pci_update_device(ACPI_HANDLE handle, device_t pci_child)
|
|||||||
device_t child;
|
device_t child;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup and remove the unused device that acpi0 creates when it walks
|
* Occasionally a PCI device may show up as an ACPI device
|
||||||
* the namespace creating devices.
|
* 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);
|
child = acpi_get_device(handle);
|
||||||
if (child != NULL) {
|
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) ==
|
KASSERT(device_get_parent(child) ==
|
||||||
devclass_get_device(devclass_find("acpi"), 0),
|
devclass_get_device(devclass_find("acpi"), 0),
|
||||||
("%s: child (%s)'s parent is not acpi0", __func__,
|
("%s: child (%s)'s parent is not acpi0", __func__,
|
||||||
acpi_name(handle)));
|
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.
|
* 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);
|
status = AcpiAttachData(handle, acpi_fake_objhandler, pci_child);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
printf("WARNING: Unable to attach object data to %s - %s\n",
|
printf("WARNING: Unable to attach object data to %s - %s\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user