diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index 8765136c5a..c508414ae2 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -135,6 +135,15 @@ enum { ACPI_ALLOCATE_BUFFER = -1, }; + +typedef struct acpi_pci_info { + uint16 segment; + uint16 bus; + uint16 device; + uint16 function; +} acpi_pci_info; + + /* * acpi_status should return ACPI specific error codes, not BeOS ones. */ @@ -248,6 +257,10 @@ struct acpi_module_info { size_t size); status_t (*enter_sleep_state)(uint8 state); status_t (*reboot)(void); + + /* PCI specific info */ + status_t (*get_pci_info)(acpi_handle pciRootBridge, acpi_handle device, + acpi_pci_info *info); }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index 02eea915ba..7bad5b2615 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -77,8 +77,8 @@ get_device_by_hid_callback(ACPI_HANDLE object, UINT32 depth, void* context, static void dump_madt() { ACPI_STATUS status; ACPI_TABLE_HEADER *madt = NULL; - ACPI_SUBTABLE_HEADER *entry; - void *end; +/* ACPI_SUBTABLE_HEADER *entry; + void *end; */ int madtCount = -1; while (true) { @@ -481,14 +481,14 @@ get_device_hid(const char *path, char *hid, size_t bufferLength) if (info.Type == ACPI_TYPE_INTEGER) { uint32 eisaId = AcpiUtDwordByteSwap(info.Integer.Value); - hid[0] = (char) ('@' + ((eisaId >> 26) & 0x1f)); - hid[1] = (char) ('@' + ((eisaId >> 21) & 0x1f)); - hid[2] = (char) ('@' + ((eisaId >> 16) & 0x1f)); - hid[3] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 12); - hid[4] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 8); - hid[5] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 4); - hid[6] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 0); - hid[7] = 0; + hid[0] = (char) ('@' + ((eisaId >> 26) & 0x1f)); + hid[1] = (char) ('@' + ((eisaId >> 21) & 0x1f)); + hid[2] = (char) ('@' + ((eisaId >> 16) & 0x1f)); + hid[3] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 12); + hid[4] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 8); + hid[5] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 4); + hid[6] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 0); + hid[7] = 0; } hid[ACPI_DEVICE_ID_LENGTH] = '\0'; @@ -705,6 +705,48 @@ reboot(void) } +status_t +get_pci_info(acpi_handle pciRootBridge, acpi_handle device, acpi_pci_info *info) +{ + ACPI_STATUS status; + ACPI_HANDLE childNode; + uint64 deviceAddress = 0; + uint64 segment = 0; + uint64 busNumber = 0; + + // We reset the structure to 0 here. Any failed evaluation means default + // values, so we don't have to do anything in the error case. + memset(info, 0, sizeof(acpi_pci_info)); + + status = AcpiUtEvaluateNumericObject(METHOD_NAME__ADR, device, + &deviceAddress); + if (status == AE_OK) { + info->device = (uint8)(deviceAddress >> 16); + info->function = (uint8)deviceAddress; + } + + status = AcpiUtEvaluateNumericObject(METHOD_NAME__SEG, pciRootBridge, + &segment); + if (status == AE_OK) + info->segment = (uint8)segment; + + status = AcpiUtEvaluateNumericObject(METHOD_NAME__BBN, pciRootBridge, + &busNumber); + if (status == AE_OK) + info->bus = (uint8)busNumber; + + // since AcpiHwDerivePciId assumes getting a child object of the device + // it iterates one step less than we need - get any child node to work + // around that + status = AcpiGetNextObject(ACPI_TYPE_METHOD, device, NULL, &childNode); + if (status != AE_OK) + return B_ERROR; + + status = AcpiHwDerivePciId((ACPI_PCI_ID*)info, pciRootBridge, childNode); + return status == AE_OK ? B_OK : B_ERROR; +} + + struct acpi_module_info gACPIModule = { { B_ACPI_MODULE_NAME, @@ -743,5 +785,6 @@ struct acpi_module_info gACPIModule = { get_possible_resources, prepare_sleep_state, enter_sleep_state, - reboot + reboot, + get_pci_info }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c index d8b80d8908..0224293ba0 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -70,7 +70,6 @@ acpi_enumerate_child_devices(device_node* node, const char* root) { char result[255]; void* counter = NULL; - device_node* parent = NULL; TRACE(("acpi_enumerate_child_devices: recursing from %s\n", root)); @@ -219,7 +218,8 @@ static struct acpi_root_info sACPIRootModule = { get_possible_resources, prepare_sleep_state, enter_sleep_state, - reboot + reboot, + get_pci_info }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h index d328048e1d..106c0678ea 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h @@ -132,6 +132,10 @@ typedef struct acpi_root_info { size_t size); status_t (*enter_sleep_state)(uint8 state); status_t (*reboot)(void); + + /* PCI specific info */ + status_t (*get_pci_info)(acpi_handle pciRootBridge, acpi_handle device, + acpi_pci_info *info); } acpi_root_info; @@ -205,6 +209,10 @@ status_t prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size); status_t enter_sleep_state(uint8 state); status_t reboot(void); + +status_t get_pci_info(acpi_handle pciRootBridge, acpi_handle device, + acpi_pci_info *info); + __END_DECLS