forked from KolibriOS/kolibrios
ddk: fix strcpy
devman: scan pci root bus git-svn-id: svn://kolibrios.org@1627 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
131
drivers/devman/pci_irq.c
Normal file
131
drivers/devman/pci_irq.c
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
#include <ddk.h>
|
||||
#include <linux/errno.h>
|
||||
#include <mutex.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <pci.h>
|
||||
#include <syscall.h>
|
||||
|
||||
#include "acpi.h"
|
||||
#include "acpi_bus.h"
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
struct acpi_prt_entry
|
||||
{
|
||||
struct list_head list;
|
||||
ACPI_PCI_ID id;
|
||||
u8 pin;
|
||||
ACPI_HANDLE link;
|
||||
u32 index; /* GSI, or link _CRS index */
|
||||
};
|
||||
|
||||
static LIST_HEAD(acpi_prt_list);
|
||||
static DEFINE_SPINLOCK(acpi_prt_lock);
|
||||
|
||||
static inline char pin_name(int pin)
|
||||
{
|
||||
return 'A' + pin - 1;
|
||||
}
|
||||
|
||||
|
||||
static int acpi_pci_irq_add_entry(ACPI_HANDLE handle, struct pci_bus *bus,
|
||||
struct acpi_pci_routing_table *prt)
|
||||
{
|
||||
struct acpi_prt_entry *entry;
|
||||
|
||||
entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses
|
||||
* 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert
|
||||
* it here.
|
||||
*/
|
||||
entry->id.Segment = pci_domain_nr(bus);
|
||||
entry->id.Bus = bus->number;
|
||||
entry->id.Device = (prt->Address >> 16) & 0xFFFF;
|
||||
entry->pin = prt->Pin + 1;
|
||||
|
||||
// do_prt_fixups(entry, prt);
|
||||
|
||||
entry->index = prt->SourceIndex;
|
||||
|
||||
/*
|
||||
* Type 1: Dynamic
|
||||
* ---------------
|
||||
* The 'source' field specifies the PCI interrupt link device used to
|
||||
* configure the IRQ assigned to this slot|dev|pin. The 'source_index'
|
||||
* indicates which resource descriptor in the resource template (of
|
||||
* the link device) this interrupt is allocated from.
|
||||
*
|
||||
* NOTE: Don't query the Link Device for IRQ information at this time
|
||||
* because Link Device enumeration may not have occurred yet
|
||||
* (e.g. exists somewhere 'below' this _PRT entry in the ACPI
|
||||
* namespace).
|
||||
*/
|
||||
if (prt->Source[0])
|
||||
AcpiGetHandle(handle, prt->Source, &entry->link);
|
||||
|
||||
/*
|
||||
* Type 2: Static
|
||||
* --------------
|
||||
* The 'source' field is NULL, and the 'source_index' field specifies
|
||||
* the IRQ value, which is hardwired to specific interrupt inputs on
|
||||
* the interrupt controller.
|
||||
*/
|
||||
|
||||
dbgprintf(PREFIX " %04x:%02x:%02x[%c] -> %s[%d]\n",
|
||||
entry->id.Segment, entry->id.Bus,
|
||||
entry->id.Device, pin_name(entry->pin),
|
||||
prt->Source, entry->index);
|
||||
|
||||
spin_lock(&acpi_prt_lock);
|
||||
list_add_tail(&entry->list, &acpi_prt_list);
|
||||
spin_unlock(&acpi_prt_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int acpi_pci_irq_add_prt(ACPI_HANDLE handle, struct pci_bus *bus)
|
||||
{
|
||||
ACPI_STATUS status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct acpi_pci_routing_table *entry;
|
||||
|
||||
/* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
|
||||
status = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
|
||||
(char *) buffer.Pointer);
|
||||
|
||||
kfree(buffer.Pointer);
|
||||
|
||||
buffer.Length = ACPI_ALLOCATE_BUFFER;
|
||||
buffer.Pointer = NULL;
|
||||
|
||||
status = AcpiGetIrqRoutingTable(handle, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
dbgprintf("AcpiGetIrqRoutingTable failed "
|
||||
"evaluating _PRT [%s]\n",AcpiFormatException(status));
|
||||
kfree(buffer.Pointer);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
entry = buffer.Pointer;
|
||||
while (entry && (entry->Length > 0)) {
|
||||
acpi_pci_irq_add_entry(handle, bus, entry);
|
||||
entry = (struct acpi_pci_routing_table *)
|
||||
((unsigned long)entry + entry->Length);
|
||||
}
|
||||
|
||||
kfree(buffer.Pointer);
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user