Add a way to look up basic PCI info for an ACPI device. It works for retrieving

the base bus number and segment which is what we're using them for. It should
work generically, however I only tested it to look up PCI bridge devices.
The logic is a subset of what is done in AcpiEvPciConfigRegionSetup when setting
up the operation region for a PCI device.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41365 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2011-05-07 16:50:46 +00:00
parent 63cffb7ee3
commit 5789be33af
4 changed files with 77 additions and 13 deletions

View File

@ -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);
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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