Index: sys/dev/acpica/acpi.c =================================================================== --- sys/dev/acpica/acpi.c +++ sys/dev/acpica/acpi.c @@ -68,6 +68,8 @@ #include #include +#include + #include static MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices"); @@ -897,13 +899,18 @@ static int acpi_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) { + ACPI_DEVICE_INFO *devinfo; struct acpi_device *ad; + u_long class; + int error; if ((ad = device_get_ivars(child)) == NULL) { device_printf(child, "device has no ivars\n"); return (ENOENT); } + error = 0; + /* ACPI and ISA compatibility ivars */ switch(index) { case ACPI_IVAR_HANDLE: @@ -923,11 +930,29 @@ case ISA_IVAR_LOGICALID: *(int *)result = acpi_isa_get_logicalid(child); break; + case PCI_IVAR_CLASS: + case PCI_IVAR_SUBCLASS: + case PCI_IVAR_PROGIF: + if (ACPI_FAILURE(AcpiGetObjectInfo(ad->ad_handle, &devinfo))) + return (ENOENT); + if ((devinfo->Valid & ACPI_VALID_CLS) != 0 && + devinfo->ClassCode.Length >= ACPI_PCICLS_STRING_SIZE) { + class = strtoul(devinfo->ClassCode.String, NULL, 16); + if (index == PCI_IVAR_CLASS) + *(uint8_t*)result = (class >> 16) & 0xff; + else if (index == PCI_IVAR_SUBCLASS) + *(uint8_t*)result = (class >> 8) & 0xff; + else + *(uint8_t*)result = (class >> 0) & 0xff; + } else + error = ENOENT; + AcpiOsFree(devinfo); + break; default: return (ENOENT); } - return (0); + return (error); } static int